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:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/editors/space_action
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/editors/space_action')
-rw-r--r--source/blender/editors/space_action/CMakeLists.txt42
-rw-r--r--source/blender/editors/space_action/action_buttons.c82
-rw-r--r--source/blender/editors/space_action/action_data.c1427
-rw-r--r--source/blender/editors/space_action/action_draw.c939
-rw-r--r--source/blender/editors/space_action/action_edit.c2556
-rw-r--r--source/blender/editors/space_action/action_intern.h30
-rw-r--r--source/blender/editors/space_action/action_ops.c138
-rw-r--r--source/blender/editors/space_action/action_select.c2605
-rw-r--r--source/blender/editors/space_action/space_action.c1445
9 files changed, 4704 insertions, 4560 deletions
diff --git a/source/blender/editors/space_action/CMakeLists.txt b/source/blender/editors/space_action/CMakeLists.txt
index 853577180bb..5251ebb1267 100644
--- a/source/blender/editors/space_action/CMakeLists.txt
+++ b/source/blender/editors/space_action/CMakeLists.txt
@@ -16,37 +16,37 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- ../include
- ../../blenkernel
- ../../blenlib
- ../../blentranslation
- ../../gpu
- ../../makesdna
- ../../makesrna
- ../../windowmanager
- ../../../../intern/guardedalloc
- ../../../../intern/glew-mx
+ ../include
+ ../../blenkernel
+ ../../blenlib
+ ../../blentranslation
+ ../../gpu
+ ../../makesdna
+ ../../makesrna
+ ../../windowmanager
+ ../../../../intern/guardedalloc
+ ../../../../intern/glew-mx
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
- action_buttons.c
- action_data.c
- action_draw.c
- action_edit.c
- action_ops.c
- action_select.c
- space_action.c
+ action_buttons.c
+ action_data.c
+ action_draw.c
+ action_edit.c
+ action_ops.c
+ action_select.c
+ space_action.c
- action_intern.h
+ action_intern.h
)
set(LIB
- bf_blenkernel
- bf_blenlib
+ bf_blenkernel
+ bf_blenlib
)
add_definitions(${GL_DEFINITIONS})
diff --git a/source/blender/editors/space_action/action_buttons.c b/source/blender/editors/space_action/action_buttons.c
index eaeeca6dfd1..a30d5f34ed0 100644
--- a/source/blender/editors/space_action/action_buttons.c
+++ b/source/blender/editors/space_action/action_buttons.c
@@ -21,7 +21,6 @@
* \ingroup spaction
*/
-
#include <string.h>
#include <stdio.h>
#include <math.h>
@@ -43,7 +42,6 @@
#include "BKE_screen.h"
#include "BKE_unit.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -56,7 +54,7 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "action_intern.h" // own include
+#include "action_intern.h" // own include
/* ******************* action editor space & buttons ************** */
@@ -65,56 +63,56 @@
void action_buttons_register(ARegionType *UNUSED(art))
{
#if 0
- PanelType *pt;
-
- // TODO: AnimData / Actions List
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype action panel properties");
- strcpy(pt->idname, "ACTION_PT_properties");
- strcpy(pt->label, N_("Active F-Curve"));
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = action_anim_panel_properties;
- pt->poll = action_anim_panel_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype action panel properties");
- strcpy(pt->idname, "ACTION_PT_key_properties");
- strcpy(pt->label, N_("Active Keyframe"));
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = action_anim_panel_key_properties;
- pt->poll = action_anim_panel_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype action panel modifiers");
- strcpy(pt->idname, "ACTION_PT_modifiers");
- strcpy(pt->label, N_("Modifiers"));
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = action_anim_panel_modifiers;
- pt->poll = action_anim_panel_poll;
- BLI_addtail(&art->paneltypes, pt);
+ PanelType *pt;
+
+ // TODO: AnimData / Actions List
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype action panel properties");
+ strcpy(pt->idname, "ACTION_PT_properties");
+ strcpy(pt->label, N_("Active F-Curve"));
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = action_anim_panel_properties;
+ pt->poll = action_anim_panel_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype action panel properties");
+ strcpy(pt->idname, "ACTION_PT_key_properties");
+ strcpy(pt->label, N_("Active Keyframe"));
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = action_anim_panel_key_properties;
+ pt->poll = action_anim_panel_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype action panel modifiers");
+ strcpy(pt->idname, "ACTION_PT_modifiers");
+ strcpy(pt->label, N_("Modifiers"));
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = action_anim_panel_modifiers;
+ pt->poll = action_anim_panel_poll;
+ BLI_addtail(&art->paneltypes, pt);
#endif
}
static int action_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = action_has_buttons_region(sa);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = action_has_buttons_region(sa);
- if (ar)
- ED_region_toggle_hidden(C, ar);
+ if (ar)
+ ED_region_toggle_hidden(C, ar);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_properties(wmOperatorType *ot)
{
- ot->name = "Toggle Sidebar";
- ot->idname = "ACTION_OT_properties";
- ot->description = "Toggle the properties region visibility";
+ ot->name = "Toggle Sidebar";
+ ot->idname = "ACTION_OT_properties";
+ ot->description = "Toggle the properties region visibility";
- ot->exec = action_properties_toggle_exec;
- ot->poll = ED_operator_action_active;
+ ot->exec = action_properties_toggle_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c
index 8ecf32a2c6c..e9670a0048d 100644
--- a/source/blender/editors/space_action/action_data.c
+++ b/source/blender/editors/space_action/action_data.c
@@ -21,13 +21,11 @@
* \ingroup spaction
*/
-
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
-
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -76,25 +74,25 @@
/* Helper function to find the active AnimData block from the Action Editor context */
AnimData *ED_actedit_animdata_from_context(bContext *C)
{
- SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- Object *ob = CTX_data_active_object(C);
- AnimData *adt = NULL;
-
- /* Get AnimData block to use */
- if (saction->mode == SACTCONT_ACTION) {
- /* Currently, "Action Editor" means object-level only... */
- if (ob) {
- adt = ob->adt;
- }
- }
- else if (saction->mode == SACTCONT_SHAPEKEY) {
- Key *key = BKE_key_from_object(ob);
- if (key) {
- adt = key->adt;
- }
- }
-
- return adt;
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ Object *ob = CTX_data_active_object(C);
+ AnimData *adt = NULL;
+
+ /* Get AnimData block to use */
+ if (saction->mode == SACTCONT_ACTION) {
+ /* Currently, "Action Editor" means object-level only... */
+ if (ob) {
+ adt = ob->adt;
+ }
+ }
+ else if (saction->mode == SACTCONT_SHAPEKEY) {
+ Key *key = BKE_key_from_object(ob);
+ if (key) {
+ adt = key->adt;
+ }
+ }
+
+ return adt;
}
/* -------------------------------------------------------------------- */
@@ -102,61 +100,61 @@ AnimData *ED_actedit_animdata_from_context(bContext *C)
/* Create new action */
static bAction *action_create_new(bContext *C, bAction *oldact)
{
- ScrArea *sa = CTX_wm_area(C);
- bAction *action;
-
- /* create action - the way to do this depends on whether we've got an
- * existing one there already, in which case we make a copy of it
- * (which is useful for "versioning" actions within the same file)
- */
- if (oldact && GS(oldact->id.name) == ID_AC) {
- /* make a copy of the existing action */
- action = BKE_action_copy(CTX_data_main(C), oldact);
- }
- else {
- /* just make a new (empty) action */
- action = BKE_action_add(CTX_data_main(C), "Action");
- }
-
- /* when creating new ID blocks, there is already 1 user (as for all new datablocks),
- * but the RNA pointer code will assign all the proper users instead, so we compensate
- * for that here
- */
- BLI_assert(action->id.us == 1);
- id_us_min(&action->id);
-
- /* set ID-Root type */
- if (sa->spacetype == SPACE_ACTION) {
- SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
-
- if (saction->mode == SACTCONT_SHAPEKEY)
- action->idroot = ID_KE;
- else
- action->idroot = ID_OB;
- }
-
- return action;
+ ScrArea *sa = CTX_wm_area(C);
+ bAction *action;
+
+ /* create action - the way to do this depends on whether we've got an
+ * existing one there already, in which case we make a copy of it
+ * (which is useful for "versioning" actions within the same file)
+ */
+ if (oldact && GS(oldact->id.name) == ID_AC) {
+ /* make a copy of the existing action */
+ action = BKE_action_copy(CTX_data_main(C), oldact);
+ }
+ else {
+ /* just make a new (empty) action */
+ action = BKE_action_add(CTX_data_main(C), "Action");
+ }
+
+ /* when creating new ID blocks, there is already 1 user (as for all new datablocks),
+ * but the RNA pointer code will assign all the proper users instead, so we compensate
+ * for that here
+ */
+ BLI_assert(action->id.us == 1);
+ id_us_min(&action->id);
+
+ /* set ID-Root type */
+ if (sa->spacetype == SPACE_ACTION) {
+ SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
+
+ if (saction->mode == SACTCONT_SHAPEKEY)
+ action->idroot = ID_KE;
+ else
+ action->idroot = ID_OB;
+ }
+
+ return action;
}
/* Change the active action used by the action editor */
static void actedit_change_action(bContext *C, bAction *act)
{
- bScreen *screen = CTX_wm_screen(C);
- SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ bScreen *screen = CTX_wm_screen(C);
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- PointerRNA ptr, idptr;
- PropertyRNA *prop;
+ PointerRNA ptr, idptr;
+ PropertyRNA *prop;
- /* create RNA pointers and get the property */
- RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, saction, &ptr);
- prop = RNA_struct_find_property(&ptr, "action");
+ /* create RNA pointers and get the property */
+ RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, saction, &ptr);
+ prop = RNA_struct_find_property(&ptr, "action");
- /* NOTE: act may be NULL here, so better to just use a cast here */
- RNA_id_pointer_create((ID *)act, &idptr);
+ /* NOTE: act may be NULL here, so better to just use a cast here */
+ RNA_id_pointer_create((ID *)act, &idptr);
- /* set the new pointer, and force a refresh */
- RNA_property_pointer_set(&ptr, prop, idptr);
- RNA_property_update(C, &ptr, prop);
+ /* set the new pointer, and force a refresh */
+ RNA_property_pointer_set(&ptr, prop, idptr);
+ RNA_property_update(C, &ptr, prop);
}
/* ******************** New Action Operator *********************** */
@@ -169,115 +167,115 @@ static void actedit_change_action(bContext *C, bAction *act)
*/
static bool action_new_poll(bContext *C)
{
- Scene *scene = CTX_data_scene(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... */
- if (ED_operator_action_active(C)) {
- SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- Object *ob = CTX_data_active_object(C);
-
- /* For now, actions are only for the active object, and on object and shapekey levels... */
- if (saction->mode == SACTCONT_ACTION) {
- /* XXX: This assumes that actions are assigned to the active object in this mode */
- if (ob) {
- if ((ob->adt == NULL) || (ob->adt->flag & ADT_NLA_EDIT_ON) == 0)
- return true;
- }
- }
- else if (saction->mode == SACTCONT_SHAPEKEY) {
- Key *key = BKE_key_from_object(ob);
- if (key) {
- if ((key->adt == NULL) || (key->adt->flag & ADT_NLA_EDIT_ON) == 0)
- return true;
- }
- }
- }
- else if (ED_operator_nla_active(C)) {
- if (!(scene->flag & SCE_NLA_EDIT_ON)) {
- return true;
- }
- }
-
- /* something failed... */
- return false;
+ Scene *scene = CTX_data_scene(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... */
+ if (ED_operator_action_active(C)) {
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ Object *ob = CTX_data_active_object(C);
+
+ /* For now, actions are only for the active object, and on object and shapekey levels... */
+ if (saction->mode == SACTCONT_ACTION) {
+ /* XXX: This assumes that actions are assigned to the active object in this mode */
+ if (ob) {
+ if ((ob->adt == NULL) || (ob->adt->flag & ADT_NLA_EDIT_ON) == 0)
+ return true;
+ }
+ }
+ else if (saction->mode == SACTCONT_SHAPEKEY) {
+ Key *key = BKE_key_from_object(ob);
+ if (key) {
+ if ((key->adt == NULL) || (key->adt->flag & ADT_NLA_EDIT_ON) == 0)
+ return true;
+ }
+ }
+ }
+ else if (ED_operator_nla_active(C)) {
+ if (!(scene->flag & SCE_NLA_EDIT_ON)) {
+ return true;
+ }
+ }
+
+ /* something failed... */
+ return false;
}
static int action_new_exec(bContext *C, wmOperator *UNUSED(op))
{
- PointerRNA ptr, idptr;
- PropertyRNA *prop;
-
- /* hook into UI */
- UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
-
- if (prop) {
- bAction *action = NULL, *oldact = NULL;
- AnimData *adt = NULL;
- PointerRNA oldptr;
-
- oldptr = RNA_property_pointer_get(&ptr, prop);
- oldact = (bAction *)oldptr.id.data;
-
- /* stash the old action to prevent it from being lost */
- if (ptr.type == &RNA_AnimData) {
- adt = ptr.data;
- }
- else if (ptr.type == &RNA_SpaceDopeSheetEditor) {
- adt = ED_actedit_animdata_from_context(C);
- }
-
- /* Perform stashing operation - But only if there is an action */
- if (adt && oldact) {
- /* stash the action */
- if (BKE_nla_action_stash(adt)) {
- /* The stash operation will remove the user already
- * (and unlink the action from the AnimData action slot).
- * Hence, we must unset the ref to the action in the
- * action editor too (if this is where we're being called from)
- * first before setting the new action once it is created,
- * or else the user gets decremented twice!
- */
- if (ptr.type == &RNA_SpaceDopeSheetEditor) {
- SpaceAction *saction = (SpaceAction *)ptr.data;
- saction->action = NULL;
- }
- }
- else {
- //printf("WARNING: Failed to stash %s. It may already exist in the NLA stack though\n", oldact->id.name);
- }
- }
-
- /* create action */
- action = action_create_new(C, oldact);
-
- /* set this new action
- * NOTE: we can't use actedit_change_action, as this function is also called from the NLA
- */
- RNA_id_pointer_create(&action->id, &idptr);
- RNA_property_pointer_set(&ptr, prop, idptr);
- RNA_property_update(C, &ptr, prop);
- }
-
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
-
- return OPERATOR_FINISHED;
+ PointerRNA ptr, idptr;
+ PropertyRNA *prop;
+
+ /* hook into UI */
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
+
+ if (prop) {
+ bAction *action = NULL, *oldact = NULL;
+ AnimData *adt = NULL;
+ PointerRNA oldptr;
+
+ oldptr = RNA_property_pointer_get(&ptr, prop);
+ oldact = (bAction *)oldptr.id.data;
+
+ /* stash the old action to prevent it from being lost */
+ if (ptr.type == &RNA_AnimData) {
+ adt = ptr.data;
+ }
+ else if (ptr.type == &RNA_SpaceDopeSheetEditor) {
+ adt = ED_actedit_animdata_from_context(C);
+ }
+
+ /* Perform stashing operation - But only if there is an action */
+ if (adt && oldact) {
+ /* stash the action */
+ if (BKE_nla_action_stash(adt)) {
+ /* The stash operation will remove the user already
+ * (and unlink the action from the AnimData action slot).
+ * Hence, we must unset the ref to the action in the
+ * action editor too (if this is where we're being called from)
+ * first before setting the new action once it is created,
+ * or else the user gets decremented twice!
+ */
+ if (ptr.type == &RNA_SpaceDopeSheetEditor) {
+ SpaceAction *saction = (SpaceAction *)ptr.data;
+ saction->action = NULL;
+ }
+ }
+ else {
+ //printf("WARNING: Failed to stash %s. It may already exist in the NLA stack though\n", oldact->id.name);
+ }
+ }
+
+ /* create action */
+ action = action_create_new(C, oldact);
+
+ /* set this new action
+ * NOTE: we can't use actedit_change_action, as this function is also called from the NLA
+ */
+ RNA_id_pointer_create(&action->id, &idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr);
+ RNA_property_update(C, &ptr, prop);
+ }
+
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
+
+ return OPERATOR_FINISHED;
}
void ACTION_OT_new(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "New Action";
- ot->idname = "ACTION_OT_new";
- ot->description = "Create new action";
+ /* identifiers */
+ ot->name = "New Action";
+ ot->idname = "ACTION_OT_new";
+ ot->description = "Create new action";
- /* api callbacks */
- ot->exec = action_new_exec;
- ot->poll = action_new_poll;
+ /* api callbacks */
+ ot->exec = action_new_exec;
+ ot->poll = action_new_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************* Action Push-Down Operator ******************** */
@@ -289,127 +287,130 @@ void ACTION_OT_new(wmOperatorType *ot)
*/
static bool action_pushdown_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);
-
- /* Check for AnimData, Actions, and that tweakmode is off */
- if (adt && saction->action) {
- /* NOTE: We check this for the AnimData block in question and not the global flag,
- * as the global flag may be left dirty by some of the browsing ops here.
- */
- if (!(adt->flag & ADT_NLA_EDIT_ON))
- return true;
- }
- }
-
- /* something failed... */
- return false;
+ if (ED_operator_action_active(C)) {
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
+
+ /* Check for AnimData, Actions, and that tweakmode is off */
+ if (adt && saction->action) {
+ /* NOTE: We check this for the AnimData block in question and not the global flag,
+ * as the global flag may be left dirty by some of the browsing ops here.
+ */
+ if (!(adt->flag & ADT_NLA_EDIT_ON))
+ return true;
+ }
+ }
+
+ /* something failed... */
+ return false;
}
static int action_pushdown_exec(bContext *C, wmOperator *op)
{
- SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- AnimData *adt = ED_actedit_animdata_from_context(C);
-
- /* Do the deed... */
- if (adt) {
- /* Perform the pushdown operation
- * - This will deal with all the AnimData-side usercounts
- */
- if (action_has_motion(adt->action) == 0) {
- /* action may not be suitable... */
- BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
- return OPERATOR_CANCELLED;
- }
- else {
- /* action can be safely added */
- BKE_nla_action_pushdown(adt);
- }
-
- /* Stop displaying this action in this editor
- * NOTE: The editor itself doesn't set a user...
- */
- saction->action = NULL;
- }
-
- /* Send notifiers that stuff has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
- return OPERATOR_FINISHED;
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
+
+ /* Do the deed... */
+ if (adt) {
+ /* Perform the pushdown operation
+ * - This will deal with all the AnimData-side usercounts
+ */
+ if (action_has_motion(adt->action) == 0) {
+ /* action may not be suitable... */
+ BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* action can be safely added */
+ BKE_nla_action_pushdown(adt);
+ }
+
+ /* Stop displaying this action in this editor
+ * NOTE: The editor itself doesn't set a user...
+ */
+ saction->action = NULL;
+ }
+
+ /* Send notifiers that stuff has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ return OPERATOR_FINISHED;
}
void ACTION_OT_push_down(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Push Down Action";
- ot->idname = "ACTION_OT_push_down";
- ot->description = "Push action down on to the NLA stack as a new strip";
+ /* identifiers */
+ ot->name = "Push Down Action";
+ ot->idname = "ACTION_OT_push_down";
+ ot->description = "Push action down on to the NLA stack as a new strip";
- /* callbacks */
- ot->exec = action_pushdown_exec;
- ot->poll = action_pushdown_poll;
+ /* callbacks */
+ ot->exec = action_pushdown_exec;
+ ot->poll = action_pushdown_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************* Action Stash Operator ******************** */
static int action_stash_exec(bContext *C, wmOperator *op)
{
- SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- AnimData *adt = ED_actedit_animdata_from_context(C);
-
- /* Perform stashing operation */
- if (adt) {
- /* don't do anything if this action is empty... */
- if (action_has_motion(adt->action) == 0) {
- /* action may not be suitable... */
- BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
- return OPERATOR_CANCELLED;
- }
- else {
- /* stash the action */
- if (BKE_nla_action_stash(adt)) {
- /* The stash operation will remove the user already,
- * so the flushing step later shouldn't double up
- * the usercount fixes. Hence, we must unset this ref
- * first before setting the new action.
- */
- saction->action = NULL;
- }
- else {
- /* action has already been added - simply warn about this, and clear */
- BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
- }
-
- /* clear action refs from editor, and then also the backing data (not necessary) */
- actedit_change_action(C, NULL);
- }
- }
-
- /* Send notifiers that stuff has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
- return OPERATOR_FINISHED;
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
+
+ /* Perform stashing operation */
+ if (adt) {
+ /* don't do anything if this action is empty... */
+ if (action_has_motion(adt->action) == 0) {
+ /* action may not be suitable... */
+ BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* stash the action */
+ if (BKE_nla_action_stash(adt)) {
+ /* The stash operation will remove the user already,
+ * so the flushing step later shouldn't double up
+ * the usercount fixes. Hence, we must unset this ref
+ * first before setting the new action.
+ */
+ saction->action = NULL;
+ }
+ else {
+ /* action has already been added - simply warn about this, and clear */
+ BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
+ }
+
+ /* clear action refs from editor, and then also the backing data (not necessary) */
+ actedit_change_action(C, NULL);
+ }
+ }
+
+ /* Send notifiers that stuff has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ return OPERATOR_FINISHED;
}
void ACTION_OT_stash(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Stash Action";
- ot->idname = "ACTION_OT_stash";
- ot->description = "Store this action in the NLA stack as a non-contributing strip for later use";
-
- /* callbacks */
- ot->exec = action_stash_exec;
- ot->poll = action_pushdown_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- ot->prop = RNA_def_boolean(ot->srna, "create_new", true, "Create New Action",
- "Create a new action once the existing one has been safely stored");
+ /* identifiers */
+ ot->name = "Stash Action";
+ ot->idname = "ACTION_OT_stash";
+ ot->description = "Store this action in the NLA stack as a non-contributing strip for later use";
+
+ /* callbacks */
+ ot->exec = action_stash_exec;
+ ot->poll = action_pushdown_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_boolean(ot->srna,
+ "create_new",
+ true,
+ "Create New Action",
+ "Create a new action once the existing one has been safely stored");
}
/* ----------------- */
@@ -420,94 +421,96 @@ void ACTION_OT_stash(wmOperatorType *ot)
*/
static bool action_stash_create_poll(bContext *C)
{
- if (ED_operator_action_active(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... */
- if (adt) {
- if (!(adt->flag & ADT_NLA_EDIT_ON))
- return true;
- }
- else {
- /* There may not be any action/animdata yet, so, just fallback to the global setting
- * (which may not be totally valid yet if the action editor was used and things are
- * now in an inconsistent state)
- */
- SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- Scene *scene = CTX_data_scene(C);
-
- if (!(scene->flag & SCE_NLA_EDIT_ON)) {
- /* For now, actions are only for the active object, and on object and shapekey levels... */
- return ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY);
- }
- }
- }
-
- /* something failed... */
- return false;
+ if (ED_operator_action_active(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... */
+ if (adt) {
+ if (!(adt->flag & ADT_NLA_EDIT_ON))
+ return true;
+ }
+ else {
+ /* There may not be any action/animdata yet, so, just fallback to the global setting
+ * (which may not be totally valid yet if the action editor was used and things are
+ * now in an inconsistent state)
+ */
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ Scene *scene = CTX_data_scene(C);
+
+ if (!(scene->flag & SCE_NLA_EDIT_ON)) {
+ /* For now, actions are only for the active object, and on object and shapekey levels... */
+ return ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY);
+ }
+ }
+ }
+
+ /* something failed... */
+ return false;
}
static int action_stash_create_exec(bContext *C, wmOperator *op)
{
- SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- AnimData *adt = ED_actedit_animdata_from_context(C);
-
- /* Check for no action... */
- if (saction->action == NULL) {
- /* just create a new action */
- bAction *action = action_create_new(C, NULL);
- actedit_change_action(C, action);
- }
- else if (adt) {
- /* Perform stashing operation */
- if (action_has_motion(adt->action) == 0) {
- /* don't do anything if this action is empty... */
- BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
- return OPERATOR_CANCELLED;
- }
- else {
- /* stash the action */
- if (BKE_nla_action_stash(adt)) {
- bAction *new_action = NULL;
-
- /* create new action not based on the old one (since the "new" operator already does that) */
- new_action = action_create_new(C, NULL);
-
- /* The stash operation will remove the user already,
- * so the flushing step later shouldn't double up
- * the usercount fixes. Hence, we must unset this ref
- * first before setting the new action.
- */
- saction->action = NULL;
- actedit_change_action(C, new_action);
- }
- else {
- /* action has already been added - simply warn about this, and clear */
- BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
- actedit_change_action(C, NULL);
- }
- }
- }
-
- /* Send notifiers that stuff has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
- return OPERATOR_FINISHED;
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
+
+ /* Check for no action... */
+ if (saction->action == NULL) {
+ /* just create a new action */
+ bAction *action = action_create_new(C, NULL);
+ actedit_change_action(C, action);
+ }
+ else if (adt) {
+ /* Perform stashing operation */
+ if (action_has_motion(adt->action) == 0) {
+ /* don't do anything if this action is empty... */
+ BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* stash the action */
+ if (BKE_nla_action_stash(adt)) {
+ bAction *new_action = NULL;
+
+ /* create new action not based on the old one (since the "new" operator already does that) */
+ new_action = action_create_new(C, NULL);
+
+ /* The stash operation will remove the user already,
+ * so the flushing step later shouldn't double up
+ * the usercount fixes. Hence, we must unset this ref
+ * first before setting the new action.
+ */
+ saction->action = NULL;
+ actedit_change_action(C, new_action);
+ }
+ else {
+ /* action has already been added - simply warn about this, and clear */
+ BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
+ actedit_change_action(C, NULL);
+ }
+ }
+ }
+
+ /* Send notifiers that stuff has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ return OPERATOR_FINISHED;
}
void ACTION_OT_stash_and_create(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Stash Action";
- ot->idname = "ACTION_OT_stash_and_create";
- ot->description = "Store this action in the NLA stack as a non-contributing strip for later use, and create a new action";
-
- /* callbacks */
- ot->exec = action_stash_create_exec;
- ot->poll = action_stash_create_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* identifiers */
+ ot->name = "Stash Action";
+ ot->idname = "ACTION_OT_stash_and_create";
+ ot->description =
+ "Store this action in the NLA stack as a non-contributing strip for later use, and create a "
+ "new action";
+
+ /* callbacks */
+ ot->exec = action_stash_create_exec;
+ ot->poll = action_stash_create_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************************************************************** */
@@ -522,146 +525,152 @@ void ACTION_OT_stash_and_create(wmOperatorType *ot)
* 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, bool force_delete)
+void ED_animedit_unlink_action(
+ bContext *C, ID *id, AnimData *adt, bAction *act, ReportList *reports, bool force_delete)
{
- 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_WARNING,
- "Action '%s' will not be saved, create Fake User or Stash in NLA Stack to retain",
- act->id.name + 2);
- }
-
- /* Clear Fake User and remove action stashing strip (if present) */
- if (force_delete) {
- /* Remove stashed strip binding this action to this datablock */
- /* XXX: we cannot unlink it from *OTHER* datablocks that may also be stashing it,
- * but GE users only seem to use/care about single-object binding for now so this
- * should be fine
- */
- if (adt) {
- NlaTrack *nlt, *nlt_next;
- NlaStrip *strip, *nstrip;
-
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt_next) {
- nlt_next = nlt->next;
-
- if (strstr(nlt->name, DATA_("[Action Stash]"))) {
- for (strip = nlt->strips.first; strip; strip = nstrip) {
- nstrip = strip->next;
-
- if (strip->act == act) {
- /* Remove this strip, and the track too if it doesn't have anything else */
- BKE_nlastrip_free(&nlt->strips, strip, true);
-
- if (nlt->strips.first == NULL) {
- BLI_assert(nstrip == NULL);
- BKE_nlatrack_free(&adt->nla_tracks, nlt, true);
- }
- }
- }
- }
- }
- }
-
- /* Clear Fake User */
- id_fake_user_clear(&act->id);
- }
-
- /* 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);
- }
- }
+ 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_WARNING,
+ "Action '%s' will not be saved, create Fake User or Stash in NLA Stack to retain",
+ act->id.name + 2);
+ }
+
+ /* Clear Fake User and remove action stashing strip (if present) */
+ if (force_delete) {
+ /* Remove stashed strip binding this action to this datablock */
+ /* XXX: we cannot unlink it from *OTHER* datablocks that may also be stashing it,
+ * but GE users only seem to use/care about single-object binding for now so this
+ * should be fine
+ */
+ if (adt) {
+ NlaTrack *nlt, *nlt_next;
+ NlaStrip *strip, *nstrip;
+
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt_next) {
+ nlt_next = nlt->next;
+
+ if (strstr(nlt->name, DATA_("[Action Stash]"))) {
+ for (strip = nlt->strips.first; strip; strip = nstrip) {
+ nstrip = strip->next;
+
+ if (strip->act == act) {
+ /* Remove this strip, and the track too if it doesn't have anything else */
+ BKE_nlastrip_free(&nlt->strips, strip, true);
+
+ if (nlt->strips.first == NULL) {
+ BLI_assert(nstrip == NULL);
+ BKE_nlatrack_free(&adt->nla_tracks, nlt, true);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Clear Fake User */
+ id_fake_user_clear(&act->id);
+ }
+
+ /* 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 bool 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);
+ 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;
- }
+ /* Only when there's an active action, in the right modes... */
+ if (saction->action && adt)
+ return true;
+ }
- /* something failed... */
- return false;
+ /* something failed... */
+ return false;
}
static int action_unlink_exec(bContext *C, wmOperator *op)
{
- AnimData *adt = ED_actedit_animdata_from_context(C);
- bool force_delete = RNA_boolean_get(op->ptr, "force_delete");
+ AnimData *adt = ED_actedit_animdata_from_context(C);
+ bool force_delete = RNA_boolean_get(op->ptr, "force_delete");
- if (adt && adt->action) {
- ED_animedit_unlink_action(C, NULL, adt, adt->action, op->reports, force_delete);
- }
+ if (adt && adt->action) {
+ ED_animedit_unlink_action(C, NULL, adt, adt->action, op->reports, force_delete);
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static int action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *evt)
{
- /* NOTE: this is hardcoded to match the behavior for the unlink button (in interface_templates.c) */
- RNA_boolean_set(op->ptr, "force_delete", evt->shift != 0);
- return action_unlink_exec(C, op);
+ /* NOTE: this is hardcoded to match the behavior for the unlink button (in interface_templates.c) */
+ RNA_boolean_set(op->ptr, "force_delete", evt->shift != 0);
+ return action_unlink_exec(C, op);
}
void ACTION_OT_unlink(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* 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->invoke = action_unlink_invoke;
- ot->exec = action_unlink_exec;
- ot->poll = action_unlink_poll;
-
- /* properties */
- prop = RNA_def_boolean(ot->srna, "force_delete", false, "Force Delete", "Clear Fake User and remove "
- "copy stashed in this data-block's NLA stack");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ PropertyRNA *prop;
+
+ /* 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->invoke = action_unlink_invoke;
+ ot->exec = action_unlink_exec;
+ ot->poll = action_unlink_poll;
+
+ /* properties */
+ prop = RNA_def_boolean(ot->srna,
+ "force_delete",
+ false,
+ "Force Delete",
+ "Clear Fake User and remove "
+ "copy stashed in this data-block's NLA stack");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ************************************************************************** */
@@ -670,282 +679,284 @@ void ACTION_OT_unlink(wmOperatorType *ot)
/* Try to find NLA Strip to use for action layer up/down tool */
static NlaStrip *action_layer_get_nlastrip(ListBase *strips, float ctime)
{
- NlaStrip *strip;
-
- for (strip = strips->first; strip; strip = strip->next) {
- /* Can we use this? */
- if (IN_RANGE_INCL(ctime, strip->start, strip->end)) {
- /* in range - use this one */
- return strip;
- }
- else if ((ctime < strip->start) && (strip->prev == NULL)) {
- /* before first - use this one */
- return strip;
- }
- else if ((ctime > strip->end) && (strip->next == NULL)) {
- /* after last - use this one */
- return strip;
- }
- }
-
- /* nothing suitable found... */
- return NULL;
+ NlaStrip *strip;
+
+ for (strip = strips->first; strip; strip = strip->next) {
+ /* Can we use this? */
+ if (IN_RANGE_INCL(ctime, strip->start, strip->end)) {
+ /* in range - use this one */
+ return strip;
+ }
+ else if ((ctime < strip->start) && (strip->prev == NULL)) {
+ /* before first - use this one */
+ return strip;
+ }
+ else if ((ctime > strip->end) && (strip->next == NULL)) {
+ /* after last - use this one */
+ return strip;
+ }
+ }
+
+ /* nothing suitable found... */
+ return NULL;
}
/* Switch NLA Strips/Actions */
-static void action_layer_switch_strip(AnimData *adt,
- NlaTrack *old_track, NlaStrip *old_strip,
- NlaTrack *nlt, NlaStrip *strip)
+static void action_layer_switch_strip(
+ AnimData *adt, NlaTrack *old_track, NlaStrip *old_strip, NlaTrack *nlt, NlaStrip *strip)
{
- /* Exit tweakmode on old strip
- * NOTE: We need to manually clear this stuff ourselves, as tweakmode exit doesn't do it
- */
- BKE_nla_tweakmode_exit(adt);
-
- if (old_strip) {
- old_strip->flag &= ~(NLASTRIP_FLAG_ACTIVE | NLASTRIP_FLAG_SELECT);
- }
- if (old_track) {
- old_track->flag &= ~(NLATRACK_ACTIVE | NLATRACK_SELECTED);
- }
-
- /* Make this one the active one instead */
- strip->flag |= (NLASTRIP_FLAG_ACTIVE | NLASTRIP_FLAG_SELECT);
- nlt->flag |= NLATRACK_ACTIVE;
-
- /* Copy over "solo" flag - This is useful for stashed actions... */
- if (old_track) {
- if (old_track->flag & NLATRACK_SOLO) {
- old_track->flag &= ~NLATRACK_SOLO;
- nlt->flag |= NLATRACK_SOLO;
- }
- }
- else {
- /* NLA muting <==> Solo Tracks */
- if (adt->flag & ADT_NLA_EVAL_OFF) {
- /* disable NLA muting */
- adt->flag &= ~ADT_NLA_EVAL_OFF;
-
- /* mark this track as being solo */
- adt->flag |= ADT_NLA_SOLO_TRACK;
- nlt->flag |= NLATRACK_SOLO;
-
- // TODO: Needs restpose flushing (when we get reference track)
- }
- }
-
- /* Enter tweakmode again - hopefully we're now "it" */
- BKE_nla_tweakmode_enter(adt);
- BLI_assert(adt->actstrip == strip);
+ /* Exit tweakmode on old strip
+ * NOTE: We need to manually clear this stuff ourselves, as tweakmode exit doesn't do it
+ */
+ BKE_nla_tweakmode_exit(adt);
+
+ if (old_strip) {
+ old_strip->flag &= ~(NLASTRIP_FLAG_ACTIVE | NLASTRIP_FLAG_SELECT);
+ }
+ if (old_track) {
+ old_track->flag &= ~(NLATRACK_ACTIVE | NLATRACK_SELECTED);
+ }
+
+ /* Make this one the active one instead */
+ strip->flag |= (NLASTRIP_FLAG_ACTIVE | NLASTRIP_FLAG_SELECT);
+ nlt->flag |= NLATRACK_ACTIVE;
+
+ /* Copy over "solo" flag - This is useful for stashed actions... */
+ if (old_track) {
+ if (old_track->flag & NLATRACK_SOLO) {
+ old_track->flag &= ~NLATRACK_SOLO;
+ nlt->flag |= NLATRACK_SOLO;
+ }
+ }
+ else {
+ /* NLA muting <==> Solo Tracks */
+ if (adt->flag & ADT_NLA_EVAL_OFF) {
+ /* disable NLA muting */
+ adt->flag &= ~ADT_NLA_EVAL_OFF;
+
+ /* mark this track as being solo */
+ adt->flag |= ADT_NLA_SOLO_TRACK;
+ nlt->flag |= NLATRACK_SOLO;
+
+ // TODO: Needs restpose flushing (when we get reference track)
+ }
+ }
+
+ /* Enter tweakmode again - hopefully we're now "it" */
+ BKE_nla_tweakmode_enter(adt);
+ BLI_assert(adt->actstrip == strip);
}
/* ********************** One Layer Up Operator ************************** */
static bool action_layer_next_poll(bContext *C)
{
- /* Action Editor's action editing modes only */
- if (ED_operator_action_active(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) {
- /* We need to check if there are any tracks above the active one
- * since the track the action comes from is not stored in AnimData
- */
- if (adt->nla_tracks.last) {
- NlaTrack *nlt = (NlaTrack *)adt->nla_tracks.last;
-
- if (nlt->flag & NLATRACK_DISABLED) {
- /* A disabled track will either be the track itself,
- * or one of the ones above it.
- *
- * If this is the top-most one, there is the possibility
- * that there is no active action. For now, we let this
- * case return true too, so that there is a natural way
- * to "move to an empty layer", even though this means
- * that we won't actually have an action.
- */
- // return (adt->tmpact != NULL);
- return true;
- }
- }
- }
- }
- }
-
- /* something failed... */
- return false;
+ /* Action Editor's action editing modes only */
+ if (ED_operator_action_active(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) {
+ /* We need to check if there are any tracks above the active one
+ * since the track the action comes from is not stored in AnimData
+ */
+ if (adt->nla_tracks.last) {
+ NlaTrack *nlt = (NlaTrack *)adt->nla_tracks.last;
+
+ if (nlt->flag & NLATRACK_DISABLED) {
+ /* A disabled track will either be the track itself,
+ * or one of the ones above it.
+ *
+ * If this is the top-most one, there is the possibility
+ * that there is no active action. For now, we let this
+ * case return true too, so that there is a natural way
+ * to "move to an empty layer", even though this means
+ * that we won't actually have an action.
+ */
+ // return (adt->tmpact != NULL);
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ /* something failed... */
+ return false;
}
static int action_layer_next_exec(bContext *C, wmOperator *op)
{
- AnimData *adt = ED_actedit_animdata_from_context(C);
- NlaTrack *act_track;
-
- Scene *scene = CTX_data_scene(C);
- float ctime = BKE_scene_frame_get(scene);
-
- /* Get active track */
- act_track = BKE_nlatrack_find_tweaked(adt);
-
- if (act_track == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Could not find current NLA Track");
- return OPERATOR_CANCELLED;
- }
-
- /* Find next action, and hook it up */
- if (act_track->next) {
- NlaTrack *nlt;
-
- /* Find next action to use */
- for (nlt = act_track->next; nlt; nlt = nlt->next) {
- NlaStrip *strip = action_layer_get_nlastrip(&nlt->strips, ctime);
-
- if (strip) {
- action_layer_switch_strip(adt, act_track, adt->actstrip, nlt, strip);
- break;
- }
- }
- }
- else {
- /* No more actions (strips) - Go back to editing the original active action
- * NOTE: This will mean exiting tweakmode...
- */
- BKE_nla_tweakmode_exit(adt);
-
- /* Deal with solo flags...
- * Assume: Solo Track == NLA Muting
- */
- if (adt->flag & ADT_NLA_SOLO_TRACK) {
- /* turn off solo flags on tracks */
- act_track->flag &= ~NLATRACK_SOLO;
- adt->flag &= ~ADT_NLA_SOLO_TRACK;
-
- /* turn on NLA muting (to keep same effect) */
- adt->flag |= ADT_NLA_EVAL_OFF;
-
- // TODO: Needs restpose flushing (when we get reference track)
- }
- }
-
- /* Update the action that this editor now uses
- * NOTE: The calls above have already handled the usercount/animdata side of things
- */
- actedit_change_action(C, adt->action);
- return OPERATOR_FINISHED;
+ AnimData *adt = ED_actedit_animdata_from_context(C);
+ NlaTrack *act_track;
+
+ Scene *scene = CTX_data_scene(C);
+ float ctime = BKE_scene_frame_get(scene);
+
+ /* Get active track */
+ act_track = BKE_nlatrack_find_tweaked(adt);
+
+ if (act_track == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Could not find current NLA Track");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Find next action, and hook it up */
+ if (act_track->next) {
+ NlaTrack *nlt;
+
+ /* Find next action to use */
+ for (nlt = act_track->next; nlt; nlt = nlt->next) {
+ NlaStrip *strip = action_layer_get_nlastrip(&nlt->strips, ctime);
+
+ if (strip) {
+ action_layer_switch_strip(adt, act_track, adt->actstrip, nlt, strip);
+ break;
+ }
+ }
+ }
+ else {
+ /* No more actions (strips) - Go back to editing the original active action
+ * NOTE: This will mean exiting tweakmode...
+ */
+ BKE_nla_tweakmode_exit(adt);
+
+ /* Deal with solo flags...
+ * Assume: Solo Track == NLA Muting
+ */
+ if (adt->flag & ADT_NLA_SOLO_TRACK) {
+ /* turn off solo flags on tracks */
+ act_track->flag &= ~NLATRACK_SOLO;
+ adt->flag &= ~ADT_NLA_SOLO_TRACK;
+
+ /* turn on NLA muting (to keep same effect) */
+ adt->flag |= ADT_NLA_EVAL_OFF;
+
+ // TODO: Needs restpose flushing (when we get reference track)
+ }
+ }
+
+ /* Update the action that this editor now uses
+ * NOTE: The calls above have already handled the usercount/animdata side of things
+ */
+ actedit_change_action(C, adt->action);
+ return OPERATOR_FINISHED;
}
void ACTION_OT_layer_next(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Next Layer";
- ot->idname = "ACTION_OT_layer_next";
- ot->description = "Switch to editing action in animation layer above the current action in the NLA Stack";
-
- /* callbacks */
- ot->exec = action_layer_next_exec;
- ot->poll = action_layer_next_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* identifiers */
+ ot->name = "Next Layer";
+ ot->idname = "ACTION_OT_layer_next";
+ ot->description =
+ "Switch to editing action in animation layer above the current action in the NLA Stack";
+
+ /* callbacks */
+ ot->exec = action_layer_next_exec;
+ ot->poll = action_layer_next_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ********************* One Layer Down Operator ************************* */
static bool action_layer_prev_poll(bContext *C)
{
- /* Action Editor's action editing modes only */
- if (ED_operator_action_active(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 */
- if (adt->nla_tracks.first) {
- NlaTrack *nlt = (NlaTrack *)adt->nla_tracks.first;
-
- /* Since the first disabled track is the track being tweaked/edited,
- * we can simplify things by only checking the first track:
- * - If it is disabled, this is the track being tweaked,
- * so there can't be anything below it
- * - Otherwise, there is at least 1 track below the tweaking
- * track that we can descend to
- */
- if ((nlt->flag & NLATRACK_DISABLED) == 0) {
- /* not disabled = there are actions below the one being tweaked */
- return true;
- }
- }
- }
- else {
- /* Normal Mode: If there are any tracks, we can try moving to those */
- return (adt->nla_tracks.first != NULL);
- }
- }
- }
-
- /* something failed... */
- return false;
+ /* Action Editor's action editing modes only */
+ if (ED_operator_action_active(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 */
+ if (adt->nla_tracks.first) {
+ NlaTrack *nlt = (NlaTrack *)adt->nla_tracks.first;
+
+ /* Since the first disabled track is the track being tweaked/edited,
+ * we can simplify things by only checking the first track:
+ * - If it is disabled, this is the track being tweaked,
+ * so there can't be anything below it
+ * - Otherwise, there is at least 1 track below the tweaking
+ * track that we can descend to
+ */
+ if ((nlt->flag & NLATRACK_DISABLED) == 0) {
+ /* not disabled = there are actions below the one being tweaked */
+ return true;
+ }
+ }
+ }
+ else {
+ /* Normal Mode: If there are any tracks, we can try moving to those */
+ return (adt->nla_tracks.first != NULL);
+ }
+ }
+ }
+
+ /* something failed... */
+ return false;
}
static int action_layer_prev_exec(bContext *C, wmOperator *op)
{
- AnimData *adt = ED_actedit_animdata_from_context(C);
- NlaTrack *act_track;
- NlaTrack *nlt;
-
- Scene *scene = CTX_data_scene(C);
- float ctime = BKE_scene_frame_get(scene);
-
- /* Sanity Check */
- if (adt == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Internal Error: Could not find Animation Data/NLA Stack to use");
- return OPERATOR_CANCELLED;
- }
-
- /* Get active track */
- act_track = BKE_nlatrack_find_tweaked(adt);
-
- /* If there is no active track, that means we are using the active action... */
- if (act_track) {
- /* Active Track - Start from the one below it */
- nlt = act_track->prev;
- }
- else {
- /* Active Action - Use the top-most track */
- nlt = adt->nla_tracks.last;
- }
-
- /* Find previous action and hook it up */
- for (; nlt; nlt = nlt->prev) {
- NlaStrip *strip = action_layer_get_nlastrip(&nlt->strips, ctime);
-
- if (strip) {
- action_layer_switch_strip(adt, act_track, adt->actstrip, nlt, strip);
- break;
- }
- }
-
- /* Update the action that this editor now uses
- * NOTE: The calls above have already handled the usercount/animdata side of things
- */
- actedit_change_action(C, adt->action);
- return OPERATOR_FINISHED;
+ AnimData *adt = ED_actedit_animdata_from_context(C);
+ NlaTrack *act_track;
+ NlaTrack *nlt;
+
+ Scene *scene = CTX_data_scene(C);
+ float ctime = BKE_scene_frame_get(scene);
+
+ /* Sanity Check */
+ if (adt == NULL) {
+ BKE_report(
+ op->reports, RPT_ERROR, "Internal Error: Could not find Animation Data/NLA Stack to use");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Get active track */
+ act_track = BKE_nlatrack_find_tweaked(adt);
+
+ /* If there is no active track, that means we are using the active action... */
+ if (act_track) {
+ /* Active Track - Start from the one below it */
+ nlt = act_track->prev;
+ }
+ else {
+ /* Active Action - Use the top-most track */
+ nlt = adt->nla_tracks.last;
+ }
+
+ /* Find previous action and hook it up */
+ for (; nlt; nlt = nlt->prev) {
+ NlaStrip *strip = action_layer_get_nlastrip(&nlt->strips, ctime);
+
+ if (strip) {
+ action_layer_switch_strip(adt, act_track, adt->actstrip, nlt, strip);
+ break;
+ }
+ }
+
+ /* Update the action that this editor now uses
+ * NOTE: The calls above have already handled the usercount/animdata side of things
+ */
+ actedit_change_action(C, adt->action);
+ return OPERATOR_FINISHED;
}
void ACTION_OT_layer_prev(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Previous Layer";
- ot->idname = "ACTION_OT_layer_prev";
- ot->description = "Switch to editing action in animation layer below the current action in the NLA Stack";
-
- /* callbacks */
- ot->exec = action_layer_prev_exec;
- ot->poll = action_layer_prev_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* identifiers */
+ ot->name = "Previous Layer";
+ ot->idname = "ACTION_OT_layer_prev";
+ ot->description =
+ "Switch to editing action in animation layer below the current action in the NLA Stack";
+
+ /* callbacks */
+ ot->exec = action_layer_prev_exec;
+ ot->poll = action_layer_prev_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************************************************************** */
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 0db1fd6eec3..b2baace1592 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -21,7 +21,6 @@
* \ingroup spaction
*/
-
/* System includes ----------------------------------------------------- */
#include <math.h>
@@ -46,10 +45,8 @@
#include "BKE_context.h"
#include "BKE_pointcache.h"
-
/* Everything from source (BIF, BDR, BSE) ------------------------------ */
-
#include "GPU_immediate.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
@@ -69,325 +66,335 @@
/* left hand part */
void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- View2D *v2d = &ar->v2d;
- float y = 0.0f;
- size_t items;
- int height;
-
- /* build list of channels to draw */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac)));
- if (height > BLI_rcti_size_y(&v2d->mask)) {
- /* don't use totrect set, as the width stays the same
- * (NOTE: this is ok here, the configuration is pretty straightforward)
- */
- v2d->tot.ymin = (float)(-height);
- }
- /* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */
- UI_view2d_sync(NULL, ac->sa, v2d, V2D_LOCK_COPY);
-
- /* loop through channels, and set up drawing depending on their type */
- { /* first pass: just the standard GL-drawing for backdrop + text */
- size_t channel_index = 0;
-
- y = (float)ACHANNEL_FIRST(ac);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
- float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
- /* check if visible */
- if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
- IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
- {
- /* draw all channels using standard channel-drawing API */
- ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index);
- }
-
- /* adjust y-position for next one */
- y -= ACHANNEL_STEP(ac);
- channel_index++;
- }
- }
- { /* second pass: widgets */
- uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
- size_t channel_index = 0;
-
- y = (float)ACHANNEL_FIRST(ac);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
- float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
- /* check if visible */
- if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
- IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
- {
- /* draw all channels using standard channel-drawing API */
- rctf channel_rect;
- BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax, yminc, ymaxc);
- ANIM_channel_draw_widgets(C, ac, ale, block, &channel_rect, channel_index);
- }
-
- /* adjust y-position for next one */
- y -= ACHANNEL_STEP(ac);
- channel_index++;
- }
-
- UI_block_end(C, block);
- UI_block_draw(C, block);
- }
-
- /* free tempolary channels */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ View2D *v2d = &ar->v2d;
+ float y = 0.0f;
+ size_t items;
+ int height;
+
+ /* build list of channels to draw */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac)));
+ if (height > BLI_rcti_size_y(&v2d->mask)) {
+ /* don't use totrect set, as the width stays the same
+ * (NOTE: this is ok here, the configuration is pretty straightforward)
+ */
+ v2d->tot.ymin = (float)(-height);
+ }
+ /* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */
+ UI_view2d_sync(NULL, ac->sa, v2d, V2D_LOCK_COPY);
+
+ /* loop through channels, and set up drawing depending on their type */
+ { /* first pass: just the standard GL-drawing for backdrop + text */
+ size_t channel_index = 0;
+
+ y = (float)ACHANNEL_FIRST(ac);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
+ float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
+ /* draw all channels using standard channel-drawing API */
+ ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index);
+ }
+
+ /* adjust y-position for next one */
+ y -= ACHANNEL_STEP(ac);
+ channel_index++;
+ }
+ }
+ { /* second pass: widgets */
+ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ size_t channel_index = 0;
+
+ y = (float)ACHANNEL_FIRST(ac);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
+ float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
+ /* draw all channels using standard channel-drawing API */
+ rctf channel_rect;
+ BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax, yminc, ymaxc);
+ ANIM_channel_draw_widgets(C, ac, ale, block, &channel_rect, channel_index);
+ }
+
+ /* adjust y-position for next one */
+ y -= ACHANNEL_STEP(ac);
+ channel_index++;
+ }
+
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
+ }
+
+ /* free tempolary channels */
+ ANIM_animdata_freelist(&anim_data);
}
/* ************************************************************************* */
/* Keyframes */
/* extra padding for lengths (to go under scrollers) */
-#define EXTRA_SCROLL_PAD 100.0f
+#define EXTRA_SCROLL_PAD 100.0f
/* draw keyframes in each channel */
void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
-
- View2D *v2d = &ar->v2d;
- bDopeSheet *ads = &saction->ads;
- AnimData *adt = NULL;
-
- float y;
-
- unsigned char col1[4], col2[4];
- unsigned char col1a[4], col2a[4];
- unsigned char col1b[4], col2b[4];
-
- const bool show_group_colors = !(saction->flag & SACTION_NODRAWGCOLORS);
-
-
- /* get theme colors */
- UI_GetThemeColor4ubv(TH_SHADE2, col2);
- UI_GetThemeColor4ubv(TH_HILITE, col1);
-
- UI_GetThemeColor4ubv(TH_GROUP, col2a);
- UI_GetThemeColor4ubv(TH_GROUP_ACTIVE, col1a);
-
- UI_GetThemeColor4ubv(TH_DOPESHEET_CHANNELOB, col1b);
- UI_GetThemeColor4ubv(TH_DOPESHEET_CHANNELSUBOB, col2b);
-
- /* build list of channels to draw */
- int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- int height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac)));
- /* don't use totrect set, as the width stays the same
- * (NOTE: this is ok here, the configuration is pretty straightforward)
- */
- v2d->tot.ymin = (float)(-height);
-
- /* first backdrop strips */
- y = (float)(-ACHANNEL_HEIGHT(ac));
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- GPU_blend(true);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
- const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
- /* check if visible */
- if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
- IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
- {
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- int sel = 0;
-
- /* determine if any need to draw channel */
- if (ale->datatype != ALE_NONE) {
- /* determine if channel is selected */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
- sel = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
-
- if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_SHAPEKEY)) {
- switch (ale->type) {
- case ANIMTYPE_SUMMARY:
- {
- /* reddish color from NLA */
- immUniformThemeColor(TH_ANIM_ACTIVE);
- break;
- }
- case ANIMTYPE_SCENE:
- case ANIMTYPE_OBJECT:
- {
- immUniformColor3ubvAlpha(col1b, sel ? col1[3] : col1b[3]);
- break;
- }
- case ANIMTYPE_FILLACTD:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- {
- immUniformColor3ubvAlpha(col2b, sel ? col1[3] : col2b[3]);
- break;
- }
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = ale->data;
- if (show_group_colors && agrp->customCol) {
- if (sel) {
- immUniformColor3ubvAlpha((unsigned char *)agrp->cs.select, col1a[3]);
- }
- else {
- immUniformColor3ubvAlpha((unsigned char *)agrp->cs.solid, col2a[3]);
- }
- }
- else {
- immUniformColor4ubv(sel ? col1a : col2a);
- }
- break;
- }
- case ANIMTYPE_FCURVE:
- {
- FCurve *fcu = ale->data;
- if (show_group_colors && fcu->grp && fcu->grp->customCol) {
- immUniformColor3ubvAlpha((unsigned char *)fcu->grp->cs.active, sel ? col1[3] : col2[3]);
- }
- else {
- immUniformColor4ubv(sel ? col1 : col2);
- }
- break;
- }
- default:
- {
- immUniformColor4ubv(sel ? col1 : col2);
- }
- }
-
- /* draw region twice: firstly backdrop, then the current range */
- immRectf(pos, v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
- }
- else if (ac->datatype == ANIMCONT_GPENCIL) {
- unsigned char *color;
- if ((show_group_colors) && (ale->type == ANIMTYPE_GPLAYER)) {
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
- unsigned char gpl_col[4];
- rgb_float_to_uchar(gpl_col, gpl->color);
- gpl_col[3] = col1[3];
-
- color = sel ? col1 : gpl_col;
- }
- else {
- color = sel ? col1 : col2;
- }
- /* frames less than one get less saturated background */
- immUniformColor4ubv(color);
- immRectf(pos, 0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
-
- /* frames one and higher get a saturated background */
- immUniformColor3ubvAlpha(color, MIN2(255, color[3] * 2));
- immRectf(pos, v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
- }
- else if (ac->datatype == ANIMCONT_MASK) {
- /* TODO --- this is a copy of gpencil */
- /* frames less than one get less saturated background */
- unsigned char *color = sel ? col1 : col2;
- immUniformColor4ubv(color);
- immRectf(pos, 0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
-
- /* frames one and higher get a saturated background */
- immUniformColor3ubvAlpha(color, MIN2(255, color[3] * 2));
- immRectf(pos, v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
- }
- }
- }
-
- /* Increment the step */
- y -= ACHANNEL_STEP(ac);
- }
- GPU_blend(false);
-
- /* black line marking 'current frame' for Time-Slide transform mode */
- if (saction->flag & SACTION_MOVING) {
- immUniformColor3f(0.0f, 0.0f, 0.0f);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, saction->timeslide, v2d->cur.ymin - EXTRA_SCROLL_PAD);
- immVertex2f(pos, saction->timeslide, v2d->cur.ymax);
- immEnd();
- }
- immUnbindProgram();
-
- /* Draw keyframes
- * 1) Only channels that are visible in the Action Editor get drawn/evaluated.
- * This is to try to optimize this for heavier data sets
- * 2) Keyframes which are out of view horizontally are disregarded
- */
- y = (float)(-ACHANNEL_HEIGHT(ac));
-
- int action_flag = saction->flag;
-
- if (saction->mode == SACTCONT_TIMELINE) {
- action_flag &= ~(SACTION_SHOW_INTERPOLATION | SACTION_SHOW_EXTREMES);
- }
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
- const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
- /* check if visible */
- if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
- IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
- {
- /* check if anything to show for this channel */
- if (ale->datatype != ALE_NONE) {
- adt = ANIM_nla_mapping_get(ac, ale);
-
- /* draw 'keyframes' for each specific datatype */
- switch (ale->datatype) {
- case ALE_ALL:
- draw_summary_channel(v2d, ale->data, y, ac->yscale_fac, action_flag);
- break;
- case ALE_SCE:
- draw_scene_channel(v2d, ads, ale->key_data, y, ac->yscale_fac, action_flag);
- break;
- case ALE_OB:
- draw_object_channel(v2d, ads, ale->key_data, y, ac->yscale_fac, action_flag);
- break;
- case ALE_ACT:
- draw_action_channel(v2d, adt, ale->key_data, y, ac->yscale_fac, action_flag);
- break;
- case ALE_GROUP:
- draw_agroup_channel(v2d, adt, ale->data, y, ac->yscale_fac, action_flag);
- break;
- case ALE_FCURVE:
- draw_fcurve_channel(v2d, adt, ale->key_data, y, ac->yscale_fac, action_flag);
- break;
- case ALE_GPFRAME:
- draw_gpl_channel(v2d, ads, ale->data, y, ac->yscale_fac, action_flag);
- break;
- case ALE_MASKLAY:
- draw_masklay_channel(v2d, ads, ale->data, y, ac->yscale_fac, action_flag);
- break;
- }
- }
- }
-
- y -= ACHANNEL_STEP(ac);
- }
-
- /* free temporary channels used for drawing */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+
+ View2D *v2d = &ar->v2d;
+ bDopeSheet *ads = &saction->ads;
+ AnimData *adt = NULL;
+
+ float y;
+
+ unsigned char col1[4], col2[4];
+ unsigned char col1a[4], col2a[4];
+ unsigned char col1b[4], col2b[4];
+
+ const bool show_group_colors = !(saction->flag & SACTION_NODRAWGCOLORS);
+
+ /* get theme colors */
+ UI_GetThemeColor4ubv(TH_SHADE2, col2);
+ UI_GetThemeColor4ubv(TH_HILITE, col1);
+
+ UI_GetThemeColor4ubv(TH_GROUP, col2a);
+ UI_GetThemeColor4ubv(TH_GROUP_ACTIVE, col1a);
+
+ UI_GetThemeColor4ubv(TH_DOPESHEET_CHANNELOB, col1b);
+ UI_GetThemeColor4ubv(TH_DOPESHEET_CHANNELSUBOB, col2b);
+
+ /* build list of channels to draw */
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ int height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac)));
+ /* don't use totrect set, as the width stays the same
+ * (NOTE: this is ok here, the configuration is pretty straightforward)
+ */
+ v2d->tot.ymin = (float)(-height);
+
+ /* first backdrop strips */
+ y = (float)(-ACHANNEL_HEIGHT(ac));
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ GPU_blend(true);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
+ const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ int sel = 0;
+
+ /* determine if any need to draw channel */
+ if (ale->datatype != ALE_NONE) {
+ /* determine if channel is selected */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
+ sel = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
+
+ if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_SHAPEKEY)) {
+ switch (ale->type) {
+ case ANIMTYPE_SUMMARY: {
+ /* reddish color from NLA */
+ immUniformThemeColor(TH_ANIM_ACTIVE);
+ break;
+ }
+ case ANIMTYPE_SCENE:
+ case ANIMTYPE_OBJECT: {
+ immUniformColor3ubvAlpha(col1b, sel ? col1[3] : col1b[3]);
+ break;
+ }
+ case ANIMTYPE_FILLACTD:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR: {
+ immUniformColor3ubvAlpha(col2b, sel ? col1[3] : col2b[3]);
+ break;
+ }
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = ale->data;
+ if (show_group_colors && agrp->customCol) {
+ if (sel) {
+ immUniformColor3ubvAlpha((unsigned char *)agrp->cs.select, col1a[3]);
+ }
+ else {
+ immUniformColor3ubvAlpha((unsigned char *)agrp->cs.solid, col2a[3]);
+ }
+ }
+ else {
+ immUniformColor4ubv(sel ? col1a : col2a);
+ }
+ break;
+ }
+ case ANIMTYPE_FCURVE: {
+ FCurve *fcu = ale->data;
+ if (show_group_colors && fcu->grp && fcu->grp->customCol) {
+ immUniformColor3ubvAlpha((unsigned char *)fcu->grp->cs.active,
+ sel ? col1[3] : col2[3]);
+ }
+ else {
+ immUniformColor4ubv(sel ? col1 : col2);
+ }
+ break;
+ }
+ default: {
+ immUniformColor4ubv(sel ? col1 : col2);
+ }
+ }
+
+ /* draw region twice: firstly backdrop, then the current range */
+ immRectf(pos,
+ v2d->cur.xmin,
+ (float)y - ACHANNEL_HEIGHT_HALF(ac),
+ v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ (float)y + ACHANNEL_HEIGHT_HALF(ac));
+ }
+ else if (ac->datatype == ANIMCONT_GPENCIL) {
+ unsigned char *color;
+ if ((show_group_colors) && (ale->type == ANIMTYPE_GPLAYER)) {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ unsigned char gpl_col[4];
+ rgb_float_to_uchar(gpl_col, gpl->color);
+ gpl_col[3] = col1[3];
+
+ color = sel ? col1 : gpl_col;
+ }
+ else {
+ color = sel ? col1 : col2;
+ }
+ /* frames less than one get less saturated background */
+ immUniformColor4ubv(color);
+ immRectf(pos,
+ 0.0f,
+ (float)y - ACHANNEL_HEIGHT_HALF(ac),
+ v2d->cur.xmin,
+ (float)y + ACHANNEL_HEIGHT_HALF(ac));
+
+ /* frames one and higher get a saturated background */
+ immUniformColor3ubvAlpha(color, MIN2(255, color[3] * 2));
+ immRectf(pos,
+ v2d->cur.xmin,
+ (float)y - ACHANNEL_HEIGHT_HALF(ac),
+ v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ (float)y + ACHANNEL_HEIGHT_HALF(ac));
+ }
+ else if (ac->datatype == ANIMCONT_MASK) {
+ /* TODO --- this is a copy of gpencil */
+ /* frames less than one get less saturated background */
+ unsigned char *color = sel ? col1 : col2;
+ immUniformColor4ubv(color);
+ immRectf(pos,
+ 0.0f,
+ (float)y - ACHANNEL_HEIGHT_HALF(ac),
+ v2d->cur.xmin,
+ (float)y + ACHANNEL_HEIGHT_HALF(ac));
+
+ /* frames one and higher get a saturated background */
+ immUniformColor3ubvAlpha(color, MIN2(255, color[3] * 2));
+ immRectf(pos,
+ v2d->cur.xmin,
+ (float)y - ACHANNEL_HEIGHT_HALF(ac),
+ v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ (float)y + ACHANNEL_HEIGHT_HALF(ac));
+ }
+ }
+ }
+
+ /* Increment the step */
+ y -= ACHANNEL_STEP(ac);
+ }
+ GPU_blend(false);
+
+ /* black line marking 'current frame' for Time-Slide transform mode */
+ if (saction->flag & SACTION_MOVING) {
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, saction->timeslide, v2d->cur.ymin - EXTRA_SCROLL_PAD);
+ immVertex2f(pos, saction->timeslide, v2d->cur.ymax);
+ immEnd();
+ }
+ immUnbindProgram();
+
+ /* Draw keyframes
+ * 1) Only channels that are visible in the Action Editor get drawn/evaluated.
+ * This is to try to optimize this for heavier data sets
+ * 2) Keyframes which are out of view horizontally are disregarded
+ */
+ y = (float)(-ACHANNEL_HEIGHT(ac));
+
+ int action_flag = saction->flag;
+
+ if (saction->mode == SACTCONT_TIMELINE) {
+ action_flag &= ~(SACTION_SHOW_INTERPOLATION | SACTION_SHOW_EXTREMES);
+ }
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
+ const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
+ /* check if anything to show for this channel */
+ if (ale->datatype != ALE_NONE) {
+ adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* draw 'keyframes' for each specific datatype */
+ switch (ale->datatype) {
+ case ALE_ALL:
+ draw_summary_channel(v2d, ale->data, y, ac->yscale_fac, action_flag);
+ break;
+ case ALE_SCE:
+ draw_scene_channel(v2d, ads, ale->key_data, y, ac->yscale_fac, action_flag);
+ break;
+ case ALE_OB:
+ draw_object_channel(v2d, ads, ale->key_data, y, ac->yscale_fac, action_flag);
+ break;
+ case ALE_ACT:
+ draw_action_channel(v2d, adt, ale->key_data, y, ac->yscale_fac, action_flag);
+ break;
+ case ALE_GROUP:
+ draw_agroup_channel(v2d, adt, ale->data, y, ac->yscale_fac, action_flag);
+ break;
+ case ALE_FCURVE:
+ draw_fcurve_channel(v2d, adt, ale->key_data, y, ac->yscale_fac, action_flag);
+ break;
+ case ALE_GPFRAME:
+ draw_gpl_channel(v2d, ads, ale->data, y, ac->yscale_fac, action_flag);
+ break;
+ case ALE_MASKLAY:
+ draw_masklay_channel(v2d, ads, ale->data, y, ac->yscale_fac, action_flag);
+ break;
+ }
+ }
+ }
+
+ y -= ACHANNEL_STEP(ac);
+ }
+
+ /* free temporary channels used for drawing */
+ ANIM_animdata_freelist(&anim_data);
}
/* ************************************************************************* */
@@ -395,148 +402,172 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
{
- PTCacheID *pid;
- ListBase pidlist;
- const float cache_draw_height = (4.0f * UI_DPI_FAC * U.pixelsize);
- float yoffs = 0.f;
-
- if (!(saction->cache_display & TIME_CACHE_DISPLAY) || (!ob))
- return;
-
- BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0);
-
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* iterate over pointcaches on the active object, and draw each one's range */
- for (pid = pidlist.first; pid; pid = pid->next) {
- float col[4];
-
- switch (pid->type) {
- case PTCACHE_TYPE_SOFTBODY:
- if (!(saction->cache_display & TIME_CACHE_SOFTBODY)) continue;
- break;
- case PTCACHE_TYPE_PARTICLES:
- if (!(saction->cache_display & TIME_CACHE_PARTICLES)) continue;
- break;
- case PTCACHE_TYPE_CLOTH:
- if (!(saction->cache_display & TIME_CACHE_CLOTH)) continue;
- break;
- case PTCACHE_TYPE_SMOKE_DOMAIN:
- case PTCACHE_TYPE_SMOKE_HIGHRES:
- if (!(saction->cache_display & TIME_CACHE_SMOKE)) continue;
- break;
- case PTCACHE_TYPE_DYNAMICPAINT:
- if (!(saction->cache_display & TIME_CACHE_DYNAMICPAINT)) continue;
- break;
- case PTCACHE_TYPE_RIGIDBODY:
- if (!(saction->cache_display & TIME_CACHE_RIGIDBODY)) continue;
- break;
- }
-
- if (pid->cache->cached_frames == NULL)
- continue;
-
- GPU_matrix_push();
- GPU_matrix_translate_2f(0.0, (float)V2D_SCROLL_HEIGHT_TEXT + yoffs);
- GPU_matrix_scale_2f(1.0, cache_draw_height);
-
- switch (pid->type) {
- case PTCACHE_TYPE_SOFTBODY:
- col[0] = 1.0; col[1] = 0.4; col[2] = 0.02;
- col[3] = 0.1;
- break;
- case PTCACHE_TYPE_PARTICLES:
- col[0] = 1.0; col[1] = 0.1; col[2] = 0.02;
- col[3] = 0.1;
- break;
- case PTCACHE_TYPE_CLOTH:
- col[0] = 0.1; col[1] = 0.1; col[2] = 0.75;
- col[3] = 0.1;
- break;
- case PTCACHE_TYPE_SMOKE_DOMAIN:
- case PTCACHE_TYPE_SMOKE_HIGHRES:
- col[0] = 0.2; col[1] = 0.2; col[2] = 0.2;
- col[3] = 0.1;
- break;
- case PTCACHE_TYPE_DYNAMICPAINT:
- col[0] = 1.0; col[1] = 0.1; col[2] = 0.75;
- col[3] = 0.1;
- break;
- case PTCACHE_TYPE_RIGIDBODY:
- col[0] = 1.0; col[1] = 0.6; col[2] = 0.0;
- col[3] = 0.1;
- break;
- default:
- col[0] = 1.0; col[1] = 0.0; col[2] = 1.0;
- col[3] = 0.1;
- BLI_assert(0);
- break;
- }
-
- const int sta = pid->cache->startframe, end = pid->cache->endframe;
-
- GPU_blend(true);
-
- immUniformColor4fv(col);
- immRectf(pos, (float)sta, 0.0, (float)end, 1.0);
-
- col[3] = 0.4f;
- if (pid->cache->flag & PTCACHE_BAKED) {
- col[0] -= 0.4f; col[1] -= 0.4f; col[2] -= 0.4f;
- }
- else if (pid->cache->flag & PTCACHE_OUTDATED) {
- col[0] += 0.4f; col[1] += 0.4f; col[2] += 0.4f;
- }
-
- immUniformColor4fv(col);
-
- {
- /* draw a quad for each chunk of consecutive cached frames */
- const int chunk_tot = 32;
- int chunk_len = 0;
- int ista = 0, iend = -1;
-
- for (int i = sta; i <= end; i++) {
- if (pid->cache->cached_frames[i - sta]) {
- if (chunk_len == 0) {
- immBeginAtMost(GPU_PRIM_TRIS, chunk_tot * 6);
- }
- if (ista > iend) {
- chunk_len++;
- ista = i;
- }
- iend = i;
- }
- else {
- if (ista <= iend) {
- immRectf_fast(pos, (float)ista - 0.5f, 0.0f, (float)iend + 0.5f, 1.0f);
- iend = ista - 1;
- }
- if (chunk_len >= chunk_tot) {
- immEnd();
- chunk_len = 0;
- }
- }
- }
- if (ista <= iend) {
- immRectf_fast(pos, (float)ista - 0.5f, 0.0f, (float)iend + 0.5f, 1.0f);
- }
- if (chunk_len != 0) {
- immEnd();
- }
- }
-
- GPU_blend(false);
-
- GPU_matrix_pop();
-
- yoffs += cache_draw_height;
- }
-
- immUnbindProgram();
-
- BLI_freelistN(&pidlist);
+ PTCacheID *pid;
+ ListBase pidlist;
+ const float cache_draw_height = (4.0f * UI_DPI_FAC * U.pixelsize);
+ float yoffs = 0.f;
+
+ if (!(saction->cache_display & TIME_CACHE_DISPLAY) || (!ob))
+ return;
+
+ BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0);
+
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* iterate over pointcaches on the active object, and draw each one's range */
+ for (pid = pidlist.first; pid; pid = pid->next) {
+ float col[4];
+
+ switch (pid->type) {
+ case PTCACHE_TYPE_SOFTBODY:
+ if (!(saction->cache_display & TIME_CACHE_SOFTBODY))
+ continue;
+ break;
+ case PTCACHE_TYPE_PARTICLES:
+ if (!(saction->cache_display & TIME_CACHE_PARTICLES))
+ continue;
+ break;
+ case PTCACHE_TYPE_CLOTH:
+ if (!(saction->cache_display & TIME_CACHE_CLOTH))
+ continue;
+ break;
+ case PTCACHE_TYPE_SMOKE_DOMAIN:
+ case PTCACHE_TYPE_SMOKE_HIGHRES:
+ if (!(saction->cache_display & TIME_CACHE_SMOKE))
+ continue;
+ break;
+ case PTCACHE_TYPE_DYNAMICPAINT:
+ if (!(saction->cache_display & TIME_CACHE_DYNAMICPAINT))
+ continue;
+ break;
+ case PTCACHE_TYPE_RIGIDBODY:
+ if (!(saction->cache_display & TIME_CACHE_RIGIDBODY))
+ continue;
+ break;
+ }
+
+ if (pid->cache->cached_frames == NULL)
+ continue;
+
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(0.0, (float)V2D_SCROLL_HEIGHT_TEXT + yoffs);
+ GPU_matrix_scale_2f(1.0, cache_draw_height);
+
+ switch (pid->type) {
+ case PTCACHE_TYPE_SOFTBODY:
+ col[0] = 1.0;
+ col[1] = 0.4;
+ col[2] = 0.02;
+ col[3] = 0.1;
+ break;
+ case PTCACHE_TYPE_PARTICLES:
+ col[0] = 1.0;
+ col[1] = 0.1;
+ col[2] = 0.02;
+ col[3] = 0.1;
+ break;
+ case PTCACHE_TYPE_CLOTH:
+ col[0] = 0.1;
+ col[1] = 0.1;
+ col[2] = 0.75;
+ col[3] = 0.1;
+ break;
+ case PTCACHE_TYPE_SMOKE_DOMAIN:
+ case PTCACHE_TYPE_SMOKE_HIGHRES:
+ col[0] = 0.2;
+ col[1] = 0.2;
+ col[2] = 0.2;
+ col[3] = 0.1;
+ break;
+ case PTCACHE_TYPE_DYNAMICPAINT:
+ col[0] = 1.0;
+ col[1] = 0.1;
+ col[2] = 0.75;
+ col[3] = 0.1;
+ break;
+ case PTCACHE_TYPE_RIGIDBODY:
+ col[0] = 1.0;
+ col[1] = 0.6;
+ col[2] = 0.0;
+ col[3] = 0.1;
+ break;
+ default:
+ col[0] = 1.0;
+ col[1] = 0.0;
+ col[2] = 1.0;
+ col[3] = 0.1;
+ BLI_assert(0);
+ break;
+ }
+
+ const int sta = pid->cache->startframe, end = pid->cache->endframe;
+
+ GPU_blend(true);
+
+ immUniformColor4fv(col);
+ immRectf(pos, (float)sta, 0.0, (float)end, 1.0);
+
+ col[3] = 0.4f;
+ if (pid->cache->flag & PTCACHE_BAKED) {
+ col[0] -= 0.4f;
+ col[1] -= 0.4f;
+ col[2] -= 0.4f;
+ }
+ else if (pid->cache->flag & PTCACHE_OUTDATED) {
+ col[0] += 0.4f;
+ col[1] += 0.4f;
+ col[2] += 0.4f;
+ }
+
+ immUniformColor4fv(col);
+
+ {
+ /* draw a quad for each chunk of consecutive cached frames */
+ const int chunk_tot = 32;
+ int chunk_len = 0;
+ int ista = 0, iend = -1;
+
+ for (int i = sta; i <= end; i++) {
+ if (pid->cache->cached_frames[i - sta]) {
+ if (chunk_len == 0) {
+ immBeginAtMost(GPU_PRIM_TRIS, chunk_tot * 6);
+ }
+ if (ista > iend) {
+ chunk_len++;
+ ista = i;
+ }
+ iend = i;
+ }
+ else {
+ if (ista <= iend) {
+ immRectf_fast(pos, (float)ista - 0.5f, 0.0f, (float)iend + 0.5f, 1.0f);
+ iend = ista - 1;
+ }
+ if (chunk_len >= chunk_tot) {
+ immEnd();
+ chunk_len = 0;
+ }
+ }
+ }
+ if (ista <= iend) {
+ immRectf_fast(pos, (float)ista - 0.5f, 0.0f, (float)iend + 0.5f, 1.0f);
+ }
+ if (chunk_len != 0) {
+ immEnd();
+ }
+ }
+
+ GPU_blend(false);
+
+ GPU_matrix_pop();
+
+ yoffs += cache_draw_height;
+ }
+
+ immUnbindProgram();
+
+ BLI_freelistN(&pidlist);
}
/* ************************************************************************* */
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index b0cc1b72b27..9ce709e1134 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -21,13 +21,11 @@
* \ingroup spaction
*/
-
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
-
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -72,7 +70,6 @@
#include "action_intern.h"
-
/* ************************************************************************** */
/* POSE MARKERS STUFF */
@@ -86,73 +83,73 @@
*/
static bool act_markers_make_local_poll(bContext *C)
{
- SpaceAction *sact = CTX_wm_space_action(C);
+ SpaceAction *sact = CTX_wm_space_action(C);
- /* 1) */
- if (sact == NULL)
- return 0;
+ /* 1) */
+ if (sact == NULL)
+ return 0;
- /* 2) */
- if (ELEM(sact->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) == 0)
- return 0;
- if (sact->action == NULL)
- return 0;
+ /* 2) */
+ if (ELEM(sact->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) == 0)
+ return 0;
+ if (sact->action == NULL)
+ return 0;
- /* 3) */
- if (sact->flag & SACTION_POSEMARKERS_SHOW)
- return 0;
+ /* 3) */
+ if (sact->flag & SACTION_POSEMARKERS_SHOW)
+ return 0;
- /* 4) */
- return ED_markers_get_first_selected(ED_context_get_markers(C)) != NULL;
+ /* 4) */
+ return ED_markers_get_first_selected(ED_context_get_markers(C)) != NULL;
}
static int act_markers_make_local_exec(bContext *C, wmOperator *UNUSED(op))
{
- ListBase *markers = ED_context_get_markers(C);
+ ListBase *markers = ED_context_get_markers(C);
- SpaceAction *sact = CTX_wm_space_action(C);
- bAction *act = (sact) ? sact->action : NULL;
+ SpaceAction *sact = CTX_wm_space_action(C);
+ bAction *act = (sact) ? sact->action : NULL;
- TimeMarker *marker, *markern = NULL;
+ TimeMarker *marker, *markern = NULL;
- /* sanity checks */
- if (ELEM(NULL, markers, act))
- return OPERATOR_CANCELLED;
+ /* sanity checks */
+ if (ELEM(NULL, markers, act))
+ return OPERATOR_CANCELLED;
- /* migrate markers */
- for (marker = markers->first; marker; marker = markern) {
- markern = marker->next;
+ /* migrate markers */
+ for (marker = markers->first; marker; marker = markern) {
+ markern = marker->next;
- /* move if marker is selected */
- if (marker->flag & SELECT) {
- BLI_remlink(markers, marker);
- BLI_addtail(&act->markers, marker);
- }
- }
+ /* move if marker is selected */
+ if (marker->flag & SELECT) {
+ BLI_remlink(markers, marker);
+ BLI_addtail(&act->markers, marker);
+ }
+ }
- /* now enable the "show posemarkers only" setting, so that we can see that something did happen */
- sact->flag |= SACTION_POSEMARKERS_SHOW;
+ /* now enable the "show posemarkers only" setting, so that we can see that something did happen */
+ sact->flag |= SACTION_POSEMARKERS_SHOW;
- /* notifiers - both sets, as this change affects both */
- WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
+ /* notifiers - both sets, as this change affects both */
+ WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_markers_make_local(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Make Markers Local";
- ot->idname = "ACTION_OT_markers_make_local";
- ot->description = "Move selected scene markers to the active Action as local 'pose' markers";
+ /* identifiers */
+ ot->name = "Make Markers Local";
+ ot->idname = "ACTION_OT_markers_make_local";
+ ot->description = "Move selected scene markers to the active Action as local 'pose' markers";
- /* callbacks */
- ot->exec = act_markers_make_local_exec;
- ot->poll = act_markers_make_local_poll;
+ /* callbacks */
+ ot->exec = act_markers_make_local_exec;
+ ot->poll = act_markers_make_local_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************************************************************** */
@@ -163,142 +160,142 @@ void ACTION_OT_markers_make_local(wmOperatorType *ot)
/* Get the min/max keyframes*/
static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const short onlySel)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- bool found = false;
-
- /* get data to filter, from Action or Dopesheet */
- /* XXX: what is sel doing here?!
- * Commented it, was breaking things (eg. the "auto preview range" tool). */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_SEL *//*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* set large values to try to override */
- *min = 999999999.0f;
- *max = -999999999.0f;
-
- /* check if any channels to set range with */
- if (anim_data.first) {
- /* go through channels, finding max extents */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- if (ale->datatype == ALE_GPFRAME) {
- bGPDlayer *gpl = ale->data;
- bGPDframe *gpf;
-
- /* find gp-frame which is less than or equal to cframe */
- for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
- const float framenum = (float)gpf->framenum;
- *min = min_ff(*min, framenum);
- *max = max_ff(*max, framenum);
- found = true;
- }
- }
- else if (ale->datatype == ALE_MASKLAY) {
- MaskLayer *masklay = ale->data;
- MaskLayerShape *masklay_shape;
-
- /* find mask layer which is less than or equal to cframe */
- for (masklay_shape = masklay->splines_shapes.first;
- masklay_shape;
- masklay_shape = masklay_shape->next)
- {
- const float framenum = (float)masklay_shape->frame;
- *min = min_ff(*min, framenum);
- *max = max_ff(*max, framenum);
- found = true;
- }
- }
- else {
- FCurve *fcu = (FCurve *)ale->key_data;
- float tmin, tmax;
-
- /* get range and apply necessary scaling before processing */
- if (calc_fcurve_range(fcu, &tmin, &tmax, onlySel, false)) {
-
- if (adt) {
- tmin = BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);
- tmax = BKE_nla_tweakedit_remap(adt, tmax, NLATIME_CONVERT_MAP);
- }
-
- /* try to set cur using these values, if they're more extreme than previously set values */
- *min = min_ff(*min, tmin);
- *max = max_ff(*max, tmax);
- found = true;
- }
- }
- }
-
- if (fabsf(*max - *min) < 0.001f) {
- *min -= 0.0005f;
- *max += 0.0005f;
- }
-
- /* free memory */
- ANIM_animdata_freelist(&anim_data);
- }
- else {
- /* set default range */
- if (ac->scene) {
- *min = (float)ac->scene->r.sfra;
- *max = (float)ac->scene->r.efra;
- }
- else {
- *min = -5;
- *max = 100;
- }
- }
-
- return found;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ bool found = false;
+
+ /* get data to filter, from Action or Dopesheet */
+ /* XXX: what is sel doing here?!
+ * Commented it, was breaking things (eg. the "auto preview range" tool). */
+ filter = (ANIMFILTER_DATA_VISIBLE |
+ ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_SEL */ /*| ANIMFILTER_CURVESONLY*/ |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* set large values to try to override */
+ *min = 999999999.0f;
+ *max = -999999999.0f;
+
+ /* check if any channels to set range with */
+ if (anim_data.first) {
+ /* go through channels, finding max extents */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ if (ale->datatype == ALE_GPFRAME) {
+ bGPDlayer *gpl = ale->data;
+ bGPDframe *gpf;
+
+ /* find gp-frame which is less than or equal to cframe */
+ for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ const float framenum = (float)gpf->framenum;
+ *min = min_ff(*min, framenum);
+ *max = max_ff(*max, framenum);
+ found = true;
+ }
+ }
+ else if (ale->datatype == ALE_MASKLAY) {
+ MaskLayer *masklay = ale->data;
+ MaskLayerShape *masklay_shape;
+
+ /* find mask layer which is less than or equal to cframe */
+ for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
+ masklay_shape = masklay_shape->next) {
+ const float framenum = (float)masklay_shape->frame;
+ *min = min_ff(*min, framenum);
+ *max = max_ff(*max, framenum);
+ found = true;
+ }
+ }
+ else {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ float tmin, tmax;
+
+ /* get range and apply necessary scaling before processing */
+ if (calc_fcurve_range(fcu, &tmin, &tmax, onlySel, false)) {
+
+ if (adt) {
+ tmin = BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);
+ tmax = BKE_nla_tweakedit_remap(adt, tmax, NLATIME_CONVERT_MAP);
+ }
+
+ /* try to set cur using these values, if they're more extreme than previously set values */
+ *min = min_ff(*min, tmin);
+ *max = max_ff(*max, tmax);
+ found = true;
+ }
+ }
+ }
+
+ if (fabsf(*max - *min) < 0.001f) {
+ *min -= 0.0005f;
+ *max += 0.0005f;
+ }
+
+ /* free memory */
+ ANIM_animdata_freelist(&anim_data);
+ }
+ else {
+ /* set default range */
+ if (ac->scene) {
+ *min = (float)ac->scene->r.sfra;
+ *max = (float)ac->scene->r.efra;
+ }
+ else {
+ *min = -5;
+ *max = 100;
+ }
+ }
+
+ return found;
}
/* ****************** Automatic Preview-Range Operator ****************** */
static int actkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
- Scene *scene;
- float min, max;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
- if (ac.scene == NULL)
- return OPERATOR_CANCELLED;
- else
- scene = ac.scene;
-
- /* set the range directly */
- get_keyframe_extents(&ac, &min, &max, false);
- scene->r.flag |= SCER_PRV_RANGE;
- scene->r.psfra = floorf(min);
- scene->r.pefra = ceilf(max);
-
- if (scene->r.psfra == scene->r.pefra) {
- scene->r.pefra = scene->r.psfra + 1;
- }
-
- /* set notifier that things have changed */
- // XXX err... there's nothing for frame ranges yet, but this should do fine too
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ Scene *scene;
+ float min, max;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+ if (ac.scene == NULL)
+ return OPERATOR_CANCELLED;
+ else
+ scene = ac.scene;
+
+ /* set the range directly */
+ get_keyframe_extents(&ac, &min, &max, false);
+ scene->r.flag |= SCER_PRV_RANGE;
+ scene->r.psfra = floorf(min);
+ scene->r.pefra = ceilf(max);
+
+ if (scene->r.psfra == scene->r.pefra) {
+ scene->r.pefra = scene->r.psfra + 1;
+ }
+
+ /* set notifier that things have changed */
+ // XXX err... there's nothing for frame ranges yet, but this should do fine too
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
+
+ return OPERATOR_FINISHED;
}
void ACTION_OT_previewrange_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Auto-Set Preview Range";
- ot->idname = "ACTION_OT_previewrange_set";
- ot->description = "Set Preview Range based on extents of selected Keyframes";
+ /* identifiers */
+ ot->name = "Auto-Set Preview Range";
+ ot->idname = "ACTION_OT_previewrange_set";
+ ot->description = "Set Preview Range based on extents of selected Keyframes";
- /* api callbacks */
- ot->exec = actkeys_previewrange_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_previewrange_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ****************** View-All Operator ****************** */
@@ -312,187 +309,186 @@ void ACTION_OT_previewrange_set(wmOperatorType *ot)
*/
static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min, float *max)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* NOTE: not bool, since we want prioritise individual channels over expanders */
- short found = 0;
- float y;
-
- /* get all items - we need to do it this way */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through all channels, finding the first one that's selected */
- y = (float)ACHANNEL_FIRST(ac);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
- /* must be selected... */
- if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) &&
- ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT))
- {
- /* update best estimate */
- *min = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
- *max = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
- /* is this high enough priority yet? */
- found = acf->channel_role;
-
- /* only stop our search when we've found an actual channel
- * - datablock expanders get less priority so that we don't abort prematurely
- */
- if (found == ACHANNEL_ROLE_CHANNEL) {
- break;
- }
- }
-
- /* adjust y-position for next one */
- y -= ACHANNEL_STEP(ac);
- }
-
- /* free all temp data */
- ANIM_animdata_freelist(&anim_data);
-
- return (found != 0);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* NOTE: not bool, since we want prioritise individual channels over expanders */
+ short found = 0;
+ float y;
+
+ /* get all items - we need to do it this way */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through all channels, finding the first one that's selected */
+ y = (float)ACHANNEL_FIRST(ac);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+
+ /* must be selected... */
+ if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) &&
+ ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT)) {
+ /* update best estimate */
+ *min = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
+ *max = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
+
+ /* is this high enough priority yet? */
+ found = acf->channel_role;
+
+ /* only stop our search when we've found an actual channel
+ * - datablock expanders get less priority so that we don't abort prematurely
+ */
+ if (found == ACHANNEL_ROLE_CHANNEL) {
+ break;
+ }
+ }
+
+ /* adjust y-position for next one */
+ y -= ACHANNEL_STEP(ac);
+ }
+
+ /* free all temp data */
+ ANIM_animdata_freelist(&anim_data);
+
+ return (found != 0);
}
static int actkeys_viewall(bContext *C, const bool only_sel)
{
- bAnimContext ac;
- View2D *v2d;
- float extra, min, max;
- bool found;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
- v2d = &ac.ar->v2d;
-
- /* set the horizontal range, with an extra offset so that the extreme keys will be in view */
- found = get_keyframe_extents(&ac, &min, &max, only_sel);
-
- if (only_sel && (found == false))
- return OPERATOR_CANCELLED;
-
- if (fabsf(max - min) < 1.0f) {
- /* Exception - center the single keyfrme */
- float xwidth = BLI_rctf_size_x(&v2d->cur);
-
- v2d->cur.xmin = min - xwidth / 2.0f;
- v2d->cur.xmax = max + xwidth / 2.0f;
- }
- else {
- /* Normal case - stretch the two keyframes out to fill the space, with extra spacing */
- v2d->cur.xmin = min;
- v2d->cur.xmax = max;
-
- extra = 0.125f * BLI_rctf_size_x(&v2d->cur);
- v2d->cur.xmin -= extra;
- v2d->cur.xmax += extra;
- }
-
- /* set vertical range */
- if (only_sel == false) {
- /* view all -> the summary channel is usually the shows everything, and resides right at the top... */
- v2d->cur.ymax = 0.0f;
- v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask);
- }
- else {
- /* locate first selected channel (or the active one), and frame those */
- float ymin = v2d->cur.ymin;
- float ymax = v2d->cur.ymax;
-
- if (actkeys_channels_get_selected_extents(&ac, &ymin, &ymax)) {
- /* recenter the view so that this range is in the middle */
- float ymid = (ymax - ymin) / 2.0f + ymin;
- float x_center;
-
- UI_view2d_center_get(v2d, &x_center, NULL);
- UI_view2d_center_set(v2d, x_center, ymid);
- }
- }
-
- /* do View2D syncing */
- UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
-
- /* just redraw this view */
- ED_area_tag_redraw(CTX_wm_area(C));
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ View2D *v2d;
+ float extra, min, max;
+ bool found;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+ v2d = &ac.ar->v2d;
+
+ /* set the horizontal range, with an extra offset so that the extreme keys will be in view */
+ found = get_keyframe_extents(&ac, &min, &max, only_sel);
+
+ if (only_sel && (found == false))
+ return OPERATOR_CANCELLED;
+
+ if (fabsf(max - min) < 1.0f) {
+ /* Exception - center the single keyfrme */
+ float xwidth = BLI_rctf_size_x(&v2d->cur);
+
+ v2d->cur.xmin = min - xwidth / 2.0f;
+ v2d->cur.xmax = max + xwidth / 2.0f;
+ }
+ else {
+ /* Normal case - stretch the two keyframes out to fill the space, with extra spacing */
+ v2d->cur.xmin = min;
+ v2d->cur.xmax = max;
+
+ extra = 0.125f * BLI_rctf_size_x(&v2d->cur);
+ v2d->cur.xmin -= extra;
+ v2d->cur.xmax += extra;
+ }
+
+ /* set vertical range */
+ if (only_sel == false) {
+ /* view all -> the summary channel is usually the shows everything, and resides right at the top... */
+ v2d->cur.ymax = 0.0f;
+ v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask);
+ }
+ else {
+ /* locate first selected channel (or the active one), and frame those */
+ float ymin = v2d->cur.ymin;
+ float ymax = v2d->cur.ymax;
+
+ if (actkeys_channels_get_selected_extents(&ac, &ymin, &ymax)) {
+ /* recenter the view so that this range is in the middle */
+ float ymid = (ymax - ymin) / 2.0f + ymin;
+ float x_center;
+
+ UI_view2d_center_get(v2d, &x_center, NULL);
+ UI_view2d_center_set(v2d, x_center, ymid);
+ }
+ }
+
+ /* do View2D syncing */
+ UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+
+ /* just redraw this view */
+ ED_area_tag_redraw(CTX_wm_area(C));
+
+ return OPERATOR_FINISHED;
}
/* ......... */
static int actkeys_viewall_exec(bContext *C, wmOperator *UNUSED(op))
{
- /* whole range */
- return actkeys_viewall(C, false);
+ /* whole range */
+ return actkeys_viewall(C, false);
}
static int actkeys_viewsel_exec(bContext *C, wmOperator *UNUSED(op))
{
- /* only selected */
- return actkeys_viewall(C, true);
+ /* only selected */
+ return actkeys_viewall(C, true);
}
/* ......... */
void ACTION_OT_view_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View All";
- ot->idname = "ACTION_OT_view_all";
- ot->description = "Reset viewable area to show full keyframe range";
+ /* identifiers */
+ ot->name = "View All";
+ ot->idname = "ACTION_OT_view_all";
+ ot->description = "Reset viewable area to show full keyframe range";
- /* api callbacks */
- ot->exec = actkeys_viewall_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_viewall_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void ACTION_OT_view_selected(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Selected";
- ot->idname = "ACTION_OT_view_selected";
- ot->description = "Reset viewable area to show selected keyframes range";
+ /* identifiers */
+ ot->name = "View Selected";
+ ot->idname = "ACTION_OT_view_selected";
+ ot->description = "Reset viewable area to show selected keyframes range";
- /* api callbacks */
- ot->exec = actkeys_viewsel_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_viewsel_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ****************** View-All Operator ****************** */
static int actkeys_view_frame_exec(bContext *C, wmOperator *op)
{
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- ANIM_center_frame(C, smooth_viewtx);
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ ANIM_center_frame(C, smooth_viewtx);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_view_frame(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Frame";
- ot->idname = "ACTION_OT_view_frame";
- ot->description = "Reset viewable area to show range around current frame";
+ /* identifiers */
+ ot->name = "View Frame";
+ ot->idname = "ACTION_OT_view_frame";
+ ot->description = "Reset viewable area to show range around current frame";
- /* api callbacks */
- ot->exec = actkeys_view_frame_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_view_frame_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************************************************************** */
@@ -503,553 +499,589 @@ void ACTION_OT_view_frame(wmOperatorType *ot)
static short copy_action_keys(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- int filter, ok = 0;
+ ListBase anim_data = {NULL, NULL};
+ int filter, ok = 0;
- /* clear buffer first */
- ANIM_fcurves_copybuf_free();
+ /* clear buffer first */
+ ANIM_fcurves_copybuf_free();
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* copy keyframes */
- ok = copy_animedit_keys(ac, &anim_data);
+ /* copy keyframes */
+ ok = copy_animedit_keys(ac, &anim_data);
- /* clean up */
- ANIM_animdata_freelist(&anim_data);
+ /* clean up */
+ ANIM_animdata_freelist(&anim_data);
- return ok;
+ return ok;
}
-
static short paste_action_keys(bAnimContext *ac,
- const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
+ const eKeyPasteOffset offset_mode,
+ const eKeyMergeMode merge_mode,
+ bool flip)
{
- ListBase anim_data = {NULL, NULL};
- int filter, ok = 0;
+ ListBase anim_data = {NULL, NULL};
+ int filter, ok = 0;
- /* filter data
- * - First time we try to filter more strictly, allowing only selected channels
- * to allow copying animation between channels
- * - Second time, we loosen things up if nothing was found the first time, allowing
- * users to just paste keyframes back into the original curve again [#31670]
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ /* filter data
+ * - First time we try to filter more strictly, allowing only selected channels
+ * to allow copying animation between channels
+ * - Second time, we loosen things up if nothing was found the first time, allowing
+ * users to just paste keyframes back into the original curve again [#31670]
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0) {
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- }
+ if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0) {
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ }
- /* paste keyframes */
- ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
+ /* paste keyframes */
+ ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
- /* clean up */
- ANIM_animdata_freelist(&anim_data);
+ /* clean up */
+ ANIM_animdata_freelist(&anim_data);
- return ok;
+ return ok;
}
/* ------------------- */
static int actkeys_copy_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* copy keyframes */
- if (ac.datatype == ANIMCONT_GPENCIL) {
- if (ED_gpencil_anim_copybuf_copy(&ac) == false) {
- /* Nothing got copied - An error about this should be been logged already */
- return OPERATOR_CANCELLED;
- }
- }
- else if (ac.datatype == ANIMCONT_MASK) {
- /* FIXME... */
- BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for mask mode");
- return OPERATOR_CANCELLED;
- }
- else {
- if (copy_action_keys(&ac)) {
- BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
- return OPERATOR_CANCELLED;
- }
- }
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* copy keyframes */
+ if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ED_gpencil_anim_copybuf_copy(&ac) == false) {
+ /* Nothing got copied - An error about this should be been logged already */
+ return OPERATOR_CANCELLED;
+ }
+ }
+ else if (ac.datatype == ANIMCONT_MASK) {
+ /* FIXME... */
+ BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for mask mode");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ if (copy_action_keys(&ac)) {
+ BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ return OPERATOR_FINISHED;
}
void ACTION_OT_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Keyframes";
- ot->idname = "ACTION_OT_copy";
- ot->description = "Copy selected keyframes to the copy/paste buffer";
+ /* identifiers */
+ ot->name = "Copy Keyframes";
+ ot->idname = "ACTION_OT_copy";
+ ot->description = "Copy selected keyframes to the copy/paste buffer";
- /* api callbacks */
- ot->exec = actkeys_copy_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_copy_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int actkeys_paste_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
-
- const eKeyPasteOffset offset_mode = RNA_enum_get(op->ptr, "offset");
- const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge");
- const bool flipped = RNA_boolean_get(op->ptr, "flipped");
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* ac.reports by default will be the global reports list, which won't show warnings */
- ac.reports = op->reports;
-
- /* paste keyframes */
- if (ac.datatype == ANIMCONT_GPENCIL) {
- if (ED_gpencil_anim_copybuf_paste(&ac, offset_mode) == false) {
- /* An error occurred - Reports should have been fired already */
- return OPERATOR_CANCELLED;
- }
- }
- else if (ac.datatype == ANIMCONT_MASK) {
- /* FIXME... */
- BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for grease pencil or mask mode");
- return OPERATOR_CANCELLED;
- }
- else {
- /* non-zero return means an error occurred while trying to paste */
- if (paste_action_keys(&ac, offset_mode, merge_mode, flipped)) {
- return OPERATOR_CANCELLED;
- }
- }
-
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+
+ const eKeyPasteOffset offset_mode = RNA_enum_get(op->ptr, "offset");
+ const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge");
+ const bool flipped = RNA_boolean_get(op->ptr, "flipped");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* ac.reports by default will be the global reports list, which won't show warnings */
+ ac.reports = op->reports;
+
+ /* paste keyframes */
+ if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ED_gpencil_anim_copybuf_paste(&ac, offset_mode) == false) {
+ /* An error occurred - Reports should have been fired already */
+ return OPERATOR_CANCELLED;
+ }
+ }
+ else if (ac.datatype == ANIMCONT_MASK) {
+ /* FIXME... */
+ BKE_report(op->reports,
+ RPT_ERROR,
+ "Keyframe pasting is not available for grease pencil or mask mode");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* non-zero return means an error occurred while trying to paste */
+ if (paste_action_keys(&ac, offset_mode, merge_mode, flipped)) {
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
}
void ACTION_OT_paste(wmOperatorType *ot)
{
- PropertyRNA *prop;
- /* identifiers */
- ot->name = "Paste Keyframes";
- ot->idname = "ACTION_OT_paste";
- ot->description = "Paste keyframes from copy/paste buffer for the selected channels, starting on the current frame";
-
- /* api callbacks */
-// ot->invoke = WM_operator_props_popup; // better wait for action redo panel
- ot->exec = actkeys_paste_exec;
- ot->poll = ED_operator_action_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* props */
- RNA_def_enum(ot->srna, "offset", rna_enum_keyframe_paste_offset_items, KEYFRAME_PASTE_OFFSET_CFRA_START, "Offset", "Paste time offset of keys");
- RNA_def_enum(ot->srna, "merge", rna_enum_keyframe_paste_merge_items, KEYFRAME_PASTE_MERGE_MIX, "Type", "Method of merging pasted keys and existing");
- prop = RNA_def_boolean(ot->srna, "flipped", false, "Flipped", "Paste keyframes from mirrored bones if they exist");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ PropertyRNA *prop;
+ /* identifiers */
+ ot->name = "Paste Keyframes";
+ ot->idname = "ACTION_OT_paste";
+ ot->description =
+ "Paste keyframes from copy/paste buffer for the selected channels, starting on the current "
+ "frame";
+
+ /* api callbacks */
+ // ot->invoke = WM_operator_props_popup; // better wait for action redo panel
+ ot->exec = actkeys_paste_exec;
+ ot->poll = ED_operator_action_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_enum(ot->srna,
+ "offset",
+ rna_enum_keyframe_paste_offset_items,
+ KEYFRAME_PASTE_OFFSET_CFRA_START,
+ "Offset",
+ "Paste time offset of keys");
+ RNA_def_enum(ot->srna,
+ "merge",
+ rna_enum_keyframe_paste_merge_items,
+ KEYFRAME_PASTE_MERGE_MIX,
+ "Type",
+ "Method of merging pasted keys and existing");
+ prop = RNA_def_boolean(
+ ot->srna, "flipped", false, "Flipped", "Paste keyframes from mirrored bones if they exist");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ******************** Insert Keyframes Operator ************************* */
/* defines for insert keyframes tool */
static const EnumPropertyItem prop_actkeys_insertkey_types[] = {
- {1, "ALL", 0, "All Channels", ""},
- {2, "SEL", 0, "Only Selected Channels", ""},
- {3, "GROUP", 0, "In Active Group", ""}, /* XXX not in all cases */
- {0, NULL, 0, NULL, NULL},
+ {1, "ALL", 0, "All Channels", ""},
+ {2, "SEL", 0, "Only Selected Channels", ""},
+ {3, "GROUP", 0, "In Active Group", ""}, /* XXX not in all cases */
+ {0, NULL, 0, NULL, NULL},
};
/* this function is responsible for inserting new keyframes */
static void insert_action_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- ListBase nla_cache = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- struct Depsgraph *depsgraph = ac->depsgraph;
- ReportList *reports = ac->reports;
- Scene *scene = ac->scene;
- ToolSettings *ts = scene->toolsettings;
- short flag = 0;
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- if (mode == 2) {
- filter |= ANIMFILTER_SEL;
- }
- else if (mode == 3) {
- filter |= ANIMFILTER_ACTGROUPED;
- }
-
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* init keyframing flag */
- flag = ANIM_get_keyframing_flags(scene, 1);
-
- /* insert keyframes */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
- float cfra = (float)CFRA;
-
- /* read value from property the F-Curve represents, or from the curve only?
- * - ale->id != NULL: Typically, this means that we have enough info to try resolving the path
- * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone,
- * so it's easier for now to just read the F-Curve directly.
- * (TODO: add the full-blown PointerRNA relative parsing case here...)
- */
- if (ale->id && !ale->owner) {
- insert_keyframe(ac->bmain, depsgraph, reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
- fcu->rna_path, fcu->array_index, cfra, ts->keyframe_type, &nla_cache, flag);
- }
- else {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* adjust current frame for NLA-scaling */
- if (adt)
- cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
-
- const float curval = evaluate_fcurve(fcu, cfra);
- insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0);
- }
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ ListBase nla_cache = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ struct Depsgraph *depsgraph = ac->depsgraph;
+ ReportList *reports = ac->reports;
+ Scene *scene = ac->scene;
+ ToolSettings *ts = scene->toolsettings;
+ short flag = 0;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ if (mode == 2) {
+ filter |= ANIMFILTER_SEL;
+ }
+ else if (mode == 3) {
+ filter |= ANIMFILTER_ACTGROUPED;
+ }
+
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* init keyframing flag */
+ flag = ANIM_get_keyframing_flags(scene, 1);
+
+ /* insert keyframes */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ float cfra = (float)CFRA;
+
+ /* read value from property the F-Curve represents, or from the curve only?
+ * - ale->id != NULL: Typically, this means that we have enough info to try resolving the path
+ * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone,
+ * so it's easier for now to just read the F-Curve directly.
+ * (TODO: add the full-blown PointerRNA relative parsing case here...)
+ */
+ if (ale->id && !ale->owner) {
+ insert_keyframe(ac->bmain,
+ depsgraph,
+ reports,
+ ale->id,
+ NULL,
+ ((fcu->grp) ? (fcu->grp->name) : (NULL)),
+ fcu->rna_path,
+ fcu->array_index,
+ cfra,
+ ts->keyframe_type,
+ &nla_cache,
+ flag);
+ }
+ else {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* adjust current frame for NLA-scaling */
+ if (adt)
+ cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+
+ const float curval = evaluate_fcurve(fcu, cfra);
+ insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0);
+ }
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* this function is for inserting new grease pencil frames */
static void insert_gpencil_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- Scene *scene = ac->scene;
- ToolSettings *ts = scene->toolsettings;
- eGP_GetFrame_Mode add_frame_mode;
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- if (mode == 2) filter |= ANIMFILTER_SEL;
-
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
-
- /* add a copy or a blank frame? */
- if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST)
- add_frame_mode = GP_GETFRAME_ADD_COPY; /* XXX: actframe may not be what we want? */
- else
- add_frame_mode = GP_GETFRAME_ADD_NEW;
-
-
- /* insert gp frames */
- for (ale = anim_data.first; ale; ale = ale->next) {
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
- BKE_gpencil_layer_getframe(gpl, CFRA, add_frame_mode);
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ Scene *scene = ac->scene;
+ ToolSettings *ts = scene->toolsettings;
+ eGP_GetFrame_Mode add_frame_mode;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ if (mode == 2)
+ filter |= ANIMFILTER_SEL;
+
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* add a copy or a blank frame? */
+ if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST)
+ add_frame_mode = GP_GETFRAME_ADD_COPY; /* XXX: actframe may not be what we want? */
+ else
+ add_frame_mode = GP_GETFRAME_ADD_NEW;
+
+ /* insert gp frames */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ BKE_gpencil_layer_getframe(gpl, CFRA, add_frame_mode);
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_insertkey_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- if (ac.datatype == ANIMCONT_MASK) {
- BKE_report(op->reports, RPT_ERROR, "Insert Keyframes is not yet implemented for this mode");
- return OPERATOR_CANCELLED;
- }
+ if (ac.datatype == ANIMCONT_MASK) {
+ BKE_report(op->reports, RPT_ERROR, "Insert Keyframes is not yet implemented for this mode");
+ return OPERATOR_CANCELLED;
+ }
- /* what channels to affect? */
- mode = RNA_enum_get(op->ptr, "type");
+ /* what channels to affect? */
+ mode = RNA_enum_get(op->ptr, "type");
- /* insert keyframes */
- if (ac.datatype == ANIMCONT_GPENCIL) {
- insert_gpencil_keys(&ac, mode);
- }
- else {
- insert_action_keys(&ac, mode);
- }
+ /* insert keyframes */
+ if (ac.datatype == ANIMCONT_GPENCIL) {
+ insert_gpencil_keys(&ac, mode);
+ }
+ else {
+ insert_action_keys(&ac, mode);
+ }
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_keyframe_insert(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Insert Keyframes";
- ot->idname = "ACTION_OT_keyframe_insert";
- ot->description = "Insert keyframes for the specified channels";
+ /* identifiers */
+ ot->name = "Insert Keyframes";
+ ot->idname = "ACTION_OT_keyframe_insert";
+ ot->description = "Insert keyframes for the specified channels";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = actkeys_insertkey_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = actkeys_insertkey_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_insertkey_types, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_insertkey_types, 0, "Type", "");
}
/* ******************** Duplicate Keyframes Operator ************************* */
static void duplicate_action_keys(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* filter data */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- }
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through filtered data and delete selected keys */
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE))
- duplicate_fcurve_keys((FCurve *)ale->key_data);
- else if (ale->type == ANIMTYPE_GPLAYER)
- ED_gplayer_frames_duplicate((bGPDlayer *)ale->data);
- else if (ale->type == ANIMTYPE_MASKLAYER)
- ED_masklayer_frames_duplicate((MaskLayer *)ale->data);
- else
- BLI_assert(0);
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data */
+ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ }
+ else {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ }
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through filtered data and delete selected keys */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE))
+ duplicate_fcurve_keys((FCurve *)ale->key_data);
+ else if (ale->type == ANIMTYPE_GPLAYER)
+ ED_gplayer_frames_duplicate((bGPDlayer *)ale->data);
+ else if (ale->type == ANIMTYPE_MASKLAYER)
+ ED_masklayer_frames_duplicate((MaskLayer *)ale->data);
+ else
+ BLI_assert(0);
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* duplicate keyframes */
- duplicate_action_keys(&ac);
+ /* duplicate keyframes */
+ duplicate_action_keys(&ac);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_duplicate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Duplicate Keyframes";
- ot->idname = "ACTION_OT_duplicate";
- ot->description = "Make a copy of all selected keyframes";
+ /* identifiers */
+ ot->name = "Duplicate Keyframes";
+ ot->idname = "ACTION_OT_duplicate";
+ ot->description = "Make a copy of all selected keyframes";
- /* api callbacks */
- ot->exec = actkeys_duplicate_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_duplicate_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Delete Keyframes Operator ************************* */
static bool delete_action_keys(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- bool changed_final = false;
-
- /* filter data */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- }
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through filtered data and delete selected keys */
- for (ale = anim_data.first; ale; ale = ale->next) {
- bool changed = false;
-
- if (ale->type == ANIMTYPE_GPLAYER) {
- changed = ED_gplayer_frames_delete((bGPDlayer *)ale->data);
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- changed = ED_masklayer_frames_delete((MaskLayer *)ale->data);
- }
- else {
- FCurve *fcu = (FCurve *)ale->key_data;
- AnimData *adt = ale->adt;
-
- /* delete selected keyframes only */
- changed = delete_fcurve_keys(fcu);
-
- /* Only delete curve too if it won't be doing anything anymore */
- if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0)) {
- ANIM_fcurve_delete_from_animdata(ac, adt, fcu);
- ale->key_data = NULL;
- }
- }
-
- if (changed) {
- ale->update |= ANIM_UPDATE_DEFAULT;
- changed_final = true;
- }
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
-
- return changed_final;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ bool changed_final = false;
+
+ /* filter data */
+ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ }
+ else {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ }
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through filtered data and delete selected keys */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ bool changed = false;
+
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ changed = ED_gplayer_frames_delete((bGPDlayer *)ale->data);
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ changed = ED_masklayer_frames_delete((MaskLayer *)ale->data);
+ }
+ else {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ AnimData *adt = ale->adt;
+
+ /* delete selected keyframes only */
+ changed = delete_fcurve_keys(fcu);
+
+ /* Only delete curve too if it won't be doing anything anymore */
+ if ((fcu->totvert == 0) &&
+ (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0)) {
+ ANIM_fcurve_delete_from_animdata(ac, adt, fcu);
+ ale->key_data = NULL;
+ }
+ }
+
+ if (changed) {
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ changed_final = true;
+ }
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
+
+ return changed_final;
}
/* ------------------- */
static int actkeys_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* delete keyframes */
- if (!delete_action_keys(&ac))
- return OPERATOR_CANCELLED;
+ /* delete keyframes */
+ if (!delete_action_keys(&ac))
+ return OPERATOR_CANCELLED;
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_delete(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete Keyframes";
- ot->idname = "ACTION_OT_delete";
- ot->description = "Remove all selected keyframes";
-
- /* api callbacks */
- ot->invoke = WM_operator_confirm;
- ot->exec = actkeys_delete_exec;
- ot->poll = ED_operator_action_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* identifiers */
+ ot->name = "Delete Keyframes";
+ ot->idname = "ACTION_OT_delete";
+ ot->description = "Remove all selected keyframes";
+
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = actkeys_delete_exec;
+ ot->poll = ED_operator_action_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Clean Keyframes Operator ************************* */
static void clean_action_keys(bAnimContext *ac, float thresh, bool clean_chan)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through filtered data and clean curves */
- for (ale = anim_data.first; ale; ale = ale->next) {
- clean_fcurve(ac, ale, thresh, clean_chan);
+ /* loop through filtered data and clean curves */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ clean_fcurve(ac, ale, thresh, clean_chan);
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_clean_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- float thresh;
- bool clean_chan;
+ bAnimContext ac;
+ float thresh;
+ bool clean_chan;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- BKE_report(op->reports, RPT_ERROR, "Not implemented");
- return OPERATOR_PASS_THROUGH;
- }
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented");
+ return OPERATOR_PASS_THROUGH;
+ }
- /* get cleaning threshold */
- thresh = RNA_float_get(op->ptr, "threshold");
- clean_chan = RNA_boolean_get(op->ptr, "channels");
+ /* get cleaning threshold */
+ thresh = RNA_float_get(op->ptr, "threshold");
+ clean_chan = RNA_boolean_get(op->ptr, "channels");
- /* clean keyframes */
- clean_action_keys(&ac, thresh, clean_chan);
+ /* clean keyframes */
+ clean_action_keys(&ac, thresh, clean_chan);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_clean(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clean Keyframes";
- ot->idname = "ACTION_OT_clean";
- ot->description = "Simplify F-Curves by removing closely spaced keyframes";
-
- /* api callbacks */
- //ot->invoke = // XXX we need that number popup for this!
- ot->exec = actkeys_clean_exec;
- ot->poll = ED_operator_action_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- ot->prop = RNA_def_float(ot->srna, "threshold", 0.001f, 0.0f, FLT_MAX, "Threshold", "", 0.0f, 1000.0f);
- RNA_def_boolean(ot->srna, "channels", false, "Channels", "");
+ /* identifiers */
+ ot->name = "Clean Keyframes";
+ ot->idname = "ACTION_OT_clean";
+ ot->description = "Simplify F-Curves by removing closely spaced keyframes";
+
+ /* api callbacks */
+ //ot->invoke = // XXX we need that number popup for this!
+ ot->exec = actkeys_clean_exec;
+ ot->poll = ED_operator_action_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_float(
+ ot->srna, "threshold", 0.001f, 0.0f, FLT_MAX, "Threshold", "", 0.0f, 1000.0f);
+ RNA_def_boolean(ot->srna, "channels", false, "Channels", "");
}
/* ******************** Sample Keyframes Operator *********************** */
@@ -1057,62 +1089,63 @@ void ACTION_OT_clean(wmOperatorType *ot)
/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
static void sample_action_keys(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through filtered data and add keys between selected keyframes on every frame */
- for (ale = anim_data.first; ale; ale = ale->next) {
- sample_fcurve((FCurve *)ale->key_data);
+ /* loop through filtered data and add keys between selected keyframes on every frame */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ sample_fcurve((FCurve *)ale->key_data);
- ale->update |= ANIM_UPDATE_DEPS;
- }
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_sample_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- BKE_report(op->reports, RPT_ERROR, "Not implemented");
- return OPERATOR_PASS_THROUGH;
- }
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented");
+ return OPERATOR_PASS_THROUGH;
+ }
- /* sample keyframes */
- sample_action_keys(&ac);
+ /* sample keyframes */
+ sample_action_keys(&ac);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_sample(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Sample Keyframes";
- ot->idname = "ACTION_OT_sample";
- ot->description = "Add keyframes on every frame between the selected keyframes";
+ /* identifiers */
+ ot->name = "Sample Keyframes";
+ ot->idname = "ACTION_OT_sample";
+ ot->description = "Add keyframes on every frame between the selected keyframes";
- /* api callbacks */
- ot->exec = actkeys_sample_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_sample_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************************************************************** */
@@ -1121,114 +1154,131 @@ void ACTION_OT_sample(wmOperatorType *ot)
/* ******************** Set Extrapolation-Type Operator *********************** */
/* defines for make/clear cyclic extrapolation tools */
-#define MAKE_CYCLIC_EXPO -1
-#define CLEAR_CYCLIC_EXPO -2
+#define MAKE_CYCLIC_EXPO -1
+#define CLEAR_CYCLIC_EXPO -2
/* defines for set extrapolation-type for selected keyframes tool */
static const EnumPropertyItem prop_actkeys_expo_types[] = {
- {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"},
- {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"},
-
- {MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"},
- {CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"},
- {0, NULL, 0, NULL, NULL},
+ {FCURVE_EXTRAPOLATE_CONSTANT,
+ "CONSTANT",
+ 0,
+ "Constant Extrapolation",
+ "Values on endpoint keyframes are held"},
+ {FCURVE_EXTRAPOLATE_LINEAR,
+ "LINEAR",
+ 0,
+ "Linear Extrapolation",
+ "Straight-line slope of end segments are extended past the endpoint keyframes"},
+
+ {MAKE_CYCLIC_EXPO,
+ "MAKE_CYCLIC",
+ 0,
+ "Make Cyclic (F-Modifier)",
+ "Add Cycles F-Modifier if one doesn't exist already"},
+ {CLEAR_CYCLIC_EXPO,
+ "CLEAR_CYCLIC",
+ 0,
+ "Clear Cyclic (F-Modifier)",
+ "Remove Cycles F-Modifier if not needed anymore"},
+ {0, NULL, 0, NULL, NULL},
};
/* this function is responsible for setting extrapolation mode for keyframes */
static void setexpo_action_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through setting mode per F-Curve */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
-
- if (mode >= 0) {
- /* just set mode setting */
- fcu->extend = mode;
- }
- else {
- /* shortcuts for managing Cycles F-Modifiers to make it easier to toggle cyclic animation
- * without having to go through FModifier UI in Graph Editor to do so
- */
- if (mode == MAKE_CYCLIC_EXPO) {
- /* only add if one doesn't exist */
- if (list_has_suitable_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, -1) == 0) {
- /* TODO: add some more preset versions which set different extrapolation options? */
- add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu);
- }
- }
- else if (mode == CLEAR_CYCLIC_EXPO) {
- /* remove all the modifiers fitting this description */
- FModifier *fcm, *fcn = NULL;
-
- for (fcm = fcu->modifiers.first; fcm; fcm = fcn) {
- fcn = fcm->next;
-
- if (fcm->type == FMODIFIER_TYPE_CYCLES)
- remove_fmodifier(&fcu->modifiers, fcm);
- }
- }
- }
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through setting mode per F-Curve */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ if (mode >= 0) {
+ /* just set mode setting */
+ fcu->extend = mode;
+ }
+ else {
+ /* shortcuts for managing Cycles F-Modifiers to make it easier to toggle cyclic animation
+ * without having to go through FModifier UI in Graph Editor to do so
+ */
+ if (mode == MAKE_CYCLIC_EXPO) {
+ /* only add if one doesn't exist */
+ if (list_has_suitable_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, -1) == 0) {
+ /* TODO: add some more preset versions which set different extrapolation options? */
+ add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu);
+ }
+ }
+ else if (mode == CLEAR_CYCLIC_EXPO) {
+ /* remove all the modifiers fitting this description */
+ FModifier *fcm, *fcn = NULL;
+
+ for (fcm = fcu->modifiers.first; fcm; fcm = fcn) {
+ fcn = fcm->next;
+
+ if (fcm->type == FMODIFIER_TYPE_CYCLES)
+ remove_fmodifier(&fcu->modifiers, fcm);
+ }
+ }
+ }
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_expo_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- BKE_report(op->reports, RPT_ERROR, "Not implemented");
- return OPERATOR_PASS_THROUGH;
- }
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented");
+ return OPERATOR_PASS_THROUGH;
+ }
- /* get handle setting mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get handle setting mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* set handle type */
- setexpo_action_keys(&ac, mode);
+ /* set handle type */
+ setexpo_action_keys(&ac, mode);
- /* set notifier that keyframe properties have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_extrapolation_type(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Keyframe Extrapolation";
- ot->idname = "ACTION_OT_extrapolation_type";
- ot->description = "Set extrapolation mode for selected F-Curves";
+ /* identifiers */
+ ot->name = "Set Keyframe Extrapolation";
+ ot->idname = "ACTION_OT_extrapolation_type";
+ ot->description = "Set extrapolation mode for selected F-Curves";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = actkeys_expo_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = actkeys_expo_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_expo_types, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_expo_types, 0, "Type", "");
}
/* ******************** Set Interpolation-Type Operator *********************** */
@@ -1236,73 +1286,76 @@ void ACTION_OT_extrapolation_type(wmOperatorType *ot)
/* this function is responsible for setting interpolation mode for keyframes */
static void setipo_action_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- KeyframeEditFunc set_cb = ANIM_editkeyframes_ipo(mode);
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through setting BezTriple interpolation
- * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
- */
- for (ale = anim_data.first; ale; ale = ale->next) {
- ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve);
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ KeyframeEditFunc set_cb = ANIM_editkeyframes_ipo(mode);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through setting BezTriple interpolation
+ * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
+ */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve);
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_ipo_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- BKE_report(op->reports, RPT_ERROR, "Not implemented");
- return OPERATOR_PASS_THROUGH;
- }
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented");
+ return OPERATOR_PASS_THROUGH;
+ }
- /* get handle setting mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get handle setting mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* set handle type */
- setipo_action_keys(&ac, mode);
+ /* set handle type */
+ setipo_action_keys(&ac, mode);
- /* set notifier that keyframe properties have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_interpolation_type(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Keyframe Interpolation";
- ot->idname = "ACTION_OT_interpolation_type";
- ot->description = "Set interpolation mode for the F-Curve segments starting from the selected keyframes";
-
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = actkeys_ipo_exec;
- ot->poll = ED_operator_action_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_beztriple_interpolation_mode_items, 0, "Type", "");
+ /* identifiers */
+ ot->name = "Set Keyframe Interpolation";
+ ot->idname = "ACTION_OT_interpolation_type";
+ ot->description =
+ "Set interpolation mode for the F-Curve segments starting from the selected keyframes";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = actkeys_ipo_exec;
+ ot->poll = ED_operator_action_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* id-props */
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", rna_enum_beztriple_interpolation_mode_items, 0, "Type", "");
}
/* ******************** Set Handle-Type Operator *********************** */
@@ -1310,81 +1363,82 @@ void ACTION_OT_interpolation_type(wmOperatorType *ot)
/* this function is responsible for setting handle-type of selected keyframes */
static void sethandles_action_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditFunc edit_cb = ANIM_editkeyframes_handles(mode);
- KeyframeEditFunc sel_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through setting flags for handles
- * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
- */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
-
- /* any selected keyframes for editing? */
- if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL)) {
- /* change type of selected handles */
- ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, edit_cb, calchandles_fcurve);
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditFunc edit_cb = ANIM_editkeyframes_handles(mode);
+ KeyframeEditFunc sel_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through setting flags for handles
+ * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
+ */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+
+ /* any selected keyframes for editing? */
+ if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL)) {
+ /* change type of selected handles */
+ ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, edit_cb, calchandles_fcurve);
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_handletype_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- BKE_report(op->reports, RPT_ERROR, "Not implemented");
- return OPERATOR_PASS_THROUGH;
- }
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented");
+ return OPERATOR_PASS_THROUGH;
+ }
- /* get handle setting mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get handle setting mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* set handle type */
- sethandles_action_keys(&ac, mode);
+ /* set handle type */
+ sethandles_action_keys(&ac, mode);
- /* set notifier that keyframe properties have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_handle_type(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Keyframe Handle Type";
- ot->idname = "ACTION_OT_handle_type";
- ot->description = "Set type of handle for selected keyframes";
+ /* identifiers */
+ ot->name = "Set Keyframe Handle Type";
+ ot->idname = "ACTION_OT_handle_type";
+ ot->description = "Set type of handle for selected keyframes";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = actkeys_handletype_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = actkeys_handletype_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_keyframe_handle_type_items, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_keyframe_handle_type_items, 0, "Type", "");
}
/* ******************** Set Keyframe-Type Operator *********************** */
@@ -1392,101 +1446,103 @@ void ACTION_OT_handle_type(wmOperatorType *ot)
/* this function is responsible for setting keyframe type for keyframes */
static void setkeytype_action_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- KeyframeEditFunc set_cb = ANIM_editkeyframes_keytype(mode);
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through setting BezTriple interpolation
- * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
- */
- for (ale = anim_data.first; ale; ale = ale->next) {
- ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, NULL);
-
- ale->update |= ANIM_UPDATE_DEPS | ANIM_UPDATE_HANDLES;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ KeyframeEditFunc set_cb = ANIM_editkeyframes_keytype(mode);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through setting BezTriple interpolation
+ * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
+ */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, NULL);
+
+ ale->update |= ANIM_UPDATE_DEPS | ANIM_UPDATE_HANDLES;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* this function is responsible for setting the keyframe type for Grease Pencil frames */
static void setkeytype_gpencil_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through each layer */
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_frames_keytype_set(ale->data, mode);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through each layer */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gplayer_frames_keytype_set(ale->data, mode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_keytype_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- if (ac.datatype == ANIMCONT_MASK) {
- BKE_report(op->reports, RPT_ERROR, "Not implemented for Masks");
- return OPERATOR_PASS_THROUGH;
- }
+ if (ac.datatype == ANIMCONT_MASK) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented for Masks");
+ return OPERATOR_PASS_THROUGH;
+ }
- /* get handle setting mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get handle setting mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* set handle type */
- if (ac.datatype == ANIMCONT_GPENCIL) {
- setkeytype_gpencil_keys(&ac, mode);
- }
- else {
- setkeytype_action_keys(&ac, mode);
- }
+ /* set handle type */
+ if (ac.datatype == ANIMCONT_GPENCIL) {
+ setkeytype_gpencil_keys(&ac, mode);
+ }
+ else {
+ setkeytype_action_keys(&ac, mode);
+ }
- /* set notifier that keyframe properties have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_keyframe_type(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Keyframe Type";
- ot->idname = "ACTION_OT_keyframe_type";
- ot->description = "Set type of keyframe for the selected keyframes";
+ /* identifiers */
+ ot->name = "Set Keyframe Type";
+ ot->idname = "ACTION_OT_keyframe_type";
+ ot->description = "Set type of keyframe for the selected keyframes";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = actkeys_keytype_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = actkeys_keytype_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_beztriple_keyframe_type_items, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_beztriple_keyframe_type_items, 0, "Type", "");
}
/* ************************************************************************** */
@@ -1496,297 +1552,323 @@ void ACTION_OT_keyframe_type(wmOperatorType *ot)
static bool actkeys_framejump_poll(bContext *C)
{
- /* prevent changes during render */
- if (G.is_rendering)
- return 0;
+ /* prevent changes during render */
+ if (G.is_rendering)
+ return 0;
- return ED_operator_action_active(C);
+ return ED_operator_action_active(C);
}
/* snap current-frame indicator to 'average time' of selected keyframe */
static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- KeyframeEditData ked = {{NULL}};
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* init edit data */
- /* loop over action data, averaging values */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
- }
- else
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
- }
-
- ANIM_animdata_freelist(&anim_data);
-
- /* set the new current frame value, based on the average time */
- if (ked.i1) {
- Scene *scene = ac.scene;
- CFRA = round_fl_to_int(ked.f1 / ked.i1);
- SUBFRA = 0.f;
- }
-
- /* set notifier that things have changed */
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ KeyframeEditData ked = {{NULL}};
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* init edit data */
+ /* loop over action data, averaging values */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ }
+ else
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+
+ /* set the new current frame value, based on the average time */
+ if (ked.i1) {
+ Scene *scene = ac.scene;
+ CFRA = round_fl_to_int(ked.f1 / ked.i1);
+ SUBFRA = 0.f;
+ }
+
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
+
+ return OPERATOR_FINISHED;
}
void ACTION_OT_frame_jump(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Jump to Keyframes";
- ot->idname = "ACTION_OT_frame_jump";
- ot->description = "Set the current frame to the average frame value of selected keyframes";
+ /* identifiers */
+ ot->name = "Jump to Keyframes";
+ ot->idname = "ACTION_OT_frame_jump";
+ ot->description = "Set the current frame to the average frame value of selected keyframes";
- /* api callbacks */
- ot->exec = actkeys_framejump_exec;
- ot->poll = actkeys_framejump_poll;
+ /* api callbacks */
+ ot->exec = actkeys_framejump_exec;
+ ot->poll = actkeys_framejump_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Snap Keyframes Operator *********************** */
/* defines for snap keyframes tool */
static const EnumPropertyItem prop_actkeys_snap_types[] = {
- {ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame",
- "Snap selected keyframes to the current frame"},
- {ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame",
- "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame offsets)"},
- {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second",
- "Snap selected keyframes to the nearest second"},
- {ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker",
- "Snap selected keyframes to the nearest marker"},
- {0, NULL, 0, NULL, NULL},
+ {ACTKEYS_SNAP_CFRA,
+ "CFRA",
+ 0,
+ "Current frame",
+ "Snap selected keyframes to the current frame"},
+ {ACTKEYS_SNAP_NEAREST_FRAME,
+ "NEAREST_FRAME",
+ 0,
+ "Nearest Frame",
+ "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame "
+ "offsets)"},
+ {ACTKEYS_SNAP_NEAREST_SECOND,
+ "NEAREST_SECOND",
+ 0,
+ "Nearest Second",
+ "Snap selected keyframes to the nearest second"},
+ {ACTKEYS_SNAP_NEAREST_MARKER,
+ "NEAREST_MARKER",
+ 0,
+ "Nearest Marker",
+ "Snap selected keyframes to the nearest marker"},
+ {0, NULL, 0, NULL, NULL},
};
/* this function is responsible for snapping keyframes to frame-times */
static void snap_action_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditData ked = {{NULL}};
- KeyframeEditFunc edit_cb;
-
- /* filter data */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- }
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* get beztriple editing callbacks */
- edit_cb = ANIM_editkeyframes_snap(mode);
-
- ked.scene = ac->scene;
- if (mode == ACTKEYS_SNAP_NEAREST_MARKER) {
- ked.list.first = (ac->markers) ? ac->markers->first : NULL;
- ked.list.last = (ac->markers) ? ac->markers->last : NULL;
- }
-
- /* snap keyframes */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_snap_frames(ale->data, ac->scene, mode);
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_masklayer_snap_frames(ale->data, ac->scene, mode);
- }
- else if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
- }
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditData ked = {{NULL}};
+ KeyframeEditFunc edit_cb;
+
+ /* filter data */
+ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
+ }
+ else {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ }
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* get beztriple editing callbacks */
+ edit_cb = ANIM_editkeyframes_snap(mode);
+
+ ked.scene = ac->scene;
+ if (mode == ACTKEYS_SNAP_NEAREST_MARKER) {
+ ked.list.first = (ac->markers) ? ac->markers->first : NULL;
+ ked.list.last = (ac->markers) ? ac->markers->last : NULL;
+ }
+
+ /* snap keyframes */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gplayer_snap_frames(ale->data, ac->scene, mode);
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ ED_masklayer_snap_frames(ale->data, ac->scene, mode);
+ }
+ else if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
+ }
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_snap_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get snapping mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get snapping mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* snap keyframes */
- snap_action_keys(&ac, mode);
+ /* snap keyframes */
+ snap_action_keys(&ac, mode);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_snap(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Snap Keys";
- ot->idname = "ACTION_OT_snap";
- ot->description = "Snap selected keyframes to the times specified";
+ /* identifiers */
+ ot->name = "Snap Keys";
+ ot->idname = "ACTION_OT_snap";
+ ot->description = "Snap selected keyframes to the times specified";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = actkeys_snap_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = actkeys_snap_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_snap_types, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_snap_types, 0, "Type", "");
}
/* ******************** Mirror Keyframes Operator *********************** */
/* defines for mirror keyframes tool */
static const EnumPropertyItem prop_actkeys_mirror_types[] = {
- {ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame",
- "Flip times of selected keyframes using the current frame as the mirror line"},
- {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0",
- "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"},
- {ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker",
- "Flip times of selected keyframes using the first selected marker as the reference point"},
- {0, NULL, 0, NULL, NULL},
+ {ACTKEYS_MIRROR_CFRA,
+ "CFRA",
+ 0,
+ "By Times over Current frame",
+ "Flip times of selected keyframes using the current frame as the mirror line"},
+ {ACTKEYS_MIRROR_XAXIS,
+ "XAXIS",
+ 0,
+ "By Values over Value=0",
+ "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"},
+ {ACTKEYS_MIRROR_MARKER,
+ "MARKER",
+ 0,
+ "By Times over First Selected Marker",
+ "Flip times of selected keyframes using the first selected marker as the reference point"},
+ {0, NULL, 0, NULL, NULL},
};
/* this function is responsible for mirroring keyframes */
static void mirror_action_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditData ked = {{NULL}};
- KeyframeEditFunc edit_cb;
-
- /* get beztriple editing callbacks */
- edit_cb = ANIM_editkeyframes_mirror(mode);
-
- ked.scene = ac->scene;
-
- /* for 'first selected marker' mode, need to find first selected marker first! */
- /* XXX should this be made into a helper func in the API? */
- if (mode == ACTKEYS_MIRROR_MARKER) {
- TimeMarker *marker = ED_markers_get_first_selected(ac->markers);
-
- if (marker)
- ked.f1 = (float)marker->frame;
- else
- return;
- }
-
- /* filter data */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- }
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* mirror keyframes */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_mirror_frames(ale->data, ac->scene, mode);
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- /* TODO */
- }
- else if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
- }
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditData ked = {{NULL}};
+ KeyframeEditFunc edit_cb;
+
+ /* get beztriple editing callbacks */
+ edit_cb = ANIM_editkeyframes_mirror(mode);
+
+ ked.scene = ac->scene;
+
+ /* for 'first selected marker' mode, need to find first selected marker first! */
+ /* XXX should this be made into a helper func in the API? */
+ if (mode == ACTKEYS_MIRROR_MARKER) {
+ TimeMarker *marker = ED_markers_get_first_selected(ac->markers);
+
+ if (marker)
+ ked.f1 = (float)marker->frame;
+ else
+ return;
+ }
+
+ /* filter data */
+ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ }
+ else {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ }
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* mirror keyframes */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gplayer_mirror_frames(ale->data, ac->scene, mode);
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ /* TODO */
+ }
+ else if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
+ }
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_mirror_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get mirroring mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get mirroring mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* mirror keyframes */
- mirror_action_keys(&ac, mode);
+ /* mirror keyframes */
+ mirror_action_keys(&ac, mode);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_mirror(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Mirror Keys";
- ot->idname = "ACTION_OT_mirror";
- ot->description = "Flip selected keyframes over the selected mirror line";
+ /* identifiers */
+ ot->name = "Mirror Keys";
+ ot->idname = "ACTION_OT_mirror";
+ ot->description = "Flip selected keyframes over the selected mirror line";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = actkeys_mirror_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = actkeys_mirror_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_mirror_types, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_mirror_types, 0, "Type", "");
}
/* ************************************************************************** */
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index 74da8aafcc8..5d86cf6faec 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -68,17 +68,17 @@ void ACTION_OT_clickselect(struct wmOperatorType *ot);
/* defines for left-right select tool */
enum eActKeys_LeftRightSelect_Mode {
- ACTKEYS_LRSEL_TEST = 0,
- ACTKEYS_LRSEL_LEFT,
- ACTKEYS_LRSEL_RIGHT,
+ ACTKEYS_LRSEL_TEST = 0,
+ ACTKEYS_LRSEL_LEFT,
+ ACTKEYS_LRSEL_RIGHT,
};
/* defines for column-select mode */
enum eActKeys_ColumnSelect_Mode {
- ACTKEYS_COLUMNSEL_KEYS = 0,
- ACTKEYS_COLUMNSEL_CFRA,
- ACTKEYS_COLUMNSEL_MARKERS_COLUMN,
- ACTKEYS_COLUMNSEL_MARKERS_BETWEEN,
+ ACTKEYS_COLUMNSEL_KEYS = 0,
+ ACTKEYS_COLUMNSEL_CFRA,
+ ACTKEYS_COLUMNSEL_MARKERS_COLUMN,
+ ACTKEYS_COLUMNSEL_MARKERS_BETWEEN,
};
/* ***************************************** */
@@ -124,20 +124,20 @@ void ACTION_OT_markers_make_local(struct wmOperatorType *ot);
* NOTE: keep in sync with eEditKeyframes_Snap (in ED_keyframes_edit.h)
*/
enum eActKeys_Snap_Mode {
- ACTKEYS_SNAP_CFRA = 1,
- ACTKEYS_SNAP_NEAREST_FRAME,
- ACTKEYS_SNAP_NEAREST_SECOND,
- ACTKEYS_SNAP_NEAREST_MARKER,
+ ACTKEYS_SNAP_CFRA = 1,
+ ACTKEYS_SNAP_NEAREST_FRAME,
+ ACTKEYS_SNAP_NEAREST_SECOND,
+ ACTKEYS_SNAP_NEAREST_MARKER,
};
/* defines for mirror keyframes
* NOTE: keep in sync with eEditKeyframes_Mirror (in ED_keyframes_edit.h)
*/
enum eActKeys_Mirror_Mode {
- ACTKEYS_MIRROR_CFRA = 1,
- ACTKEYS_MIRROR_YAXIS,
- ACTKEYS_MIRROR_XAXIS,
- ACTKEYS_MIRROR_MARKER,
+ ACTKEYS_MIRROR_CFRA = 1,
+ ACTKEYS_MIRROR_YAXIS,
+ ACTKEYS_MIRROR_XAXIS,
+ ACTKEYS_MIRROR_MARKER,
};
/* ***************************************** */
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 87b9ee4e1ef..d5ddf974284 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -21,14 +21,11 @@
* \ingroup spaction
*/
-
#include <stdlib.h>
#include <math.h>
-
#include "DNA_space_types.h"
-
#include "ED_anim_api.h"
#include "ED_markers.h"
#include "ED_transform.h"
@@ -46,68 +43,69 @@
void action_operatortypes(void)
{
- /* view */
- WM_operatortype_append(ACTION_OT_properties);
-
- /* keyframes */
- /* selection */
- WM_operatortype_append(ACTION_OT_clickselect);
- WM_operatortype_append(ACTION_OT_select_all);
- WM_operatortype_append(ACTION_OT_select_box);
- WM_operatortype_append(ACTION_OT_select_lasso);
- WM_operatortype_append(ACTION_OT_select_circle);
- WM_operatortype_append(ACTION_OT_select_column);
- WM_operatortype_append(ACTION_OT_select_linked);
- WM_operatortype_append(ACTION_OT_select_more);
- WM_operatortype_append(ACTION_OT_select_less);
- WM_operatortype_append(ACTION_OT_select_leftright);
-
- /* editing */
- WM_operatortype_append(ACTION_OT_snap);
- WM_operatortype_append(ACTION_OT_mirror);
- WM_operatortype_append(ACTION_OT_frame_jump);
- WM_operatortype_append(ACTION_OT_handle_type);
- WM_operatortype_append(ACTION_OT_interpolation_type);
- WM_operatortype_append(ACTION_OT_extrapolation_type);
- WM_operatortype_append(ACTION_OT_keyframe_type);
- WM_operatortype_append(ACTION_OT_sample);
- WM_operatortype_append(ACTION_OT_clean);
- WM_operatortype_append(ACTION_OT_delete);
- WM_operatortype_append(ACTION_OT_duplicate);
- WM_operatortype_append(ACTION_OT_keyframe_insert);
- WM_operatortype_append(ACTION_OT_copy);
- 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);
-
- WM_operatortype_append(ACTION_OT_layer_next);
- WM_operatortype_append(ACTION_OT_layer_prev);
-
- WM_operatortype_append(ACTION_OT_previewrange_set);
- WM_operatortype_append(ACTION_OT_view_all);
- WM_operatortype_append(ACTION_OT_view_selected);
- WM_operatortype_append(ACTION_OT_view_frame);
-
- WM_operatortype_append(ACTION_OT_markers_make_local);
+ /* view */
+ WM_operatortype_append(ACTION_OT_properties);
+
+ /* keyframes */
+ /* selection */
+ WM_operatortype_append(ACTION_OT_clickselect);
+ WM_operatortype_append(ACTION_OT_select_all);
+ WM_operatortype_append(ACTION_OT_select_box);
+ WM_operatortype_append(ACTION_OT_select_lasso);
+ WM_operatortype_append(ACTION_OT_select_circle);
+ WM_operatortype_append(ACTION_OT_select_column);
+ WM_operatortype_append(ACTION_OT_select_linked);
+ WM_operatortype_append(ACTION_OT_select_more);
+ WM_operatortype_append(ACTION_OT_select_less);
+ WM_operatortype_append(ACTION_OT_select_leftright);
+
+ /* editing */
+ WM_operatortype_append(ACTION_OT_snap);
+ WM_operatortype_append(ACTION_OT_mirror);
+ WM_operatortype_append(ACTION_OT_frame_jump);
+ WM_operatortype_append(ACTION_OT_handle_type);
+ WM_operatortype_append(ACTION_OT_interpolation_type);
+ WM_operatortype_append(ACTION_OT_extrapolation_type);
+ WM_operatortype_append(ACTION_OT_keyframe_type);
+ WM_operatortype_append(ACTION_OT_sample);
+ WM_operatortype_append(ACTION_OT_clean);
+ WM_operatortype_append(ACTION_OT_delete);
+ WM_operatortype_append(ACTION_OT_duplicate);
+ WM_operatortype_append(ACTION_OT_keyframe_insert);
+ WM_operatortype_append(ACTION_OT_copy);
+ 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);
+
+ WM_operatortype_append(ACTION_OT_layer_next);
+ WM_operatortype_append(ACTION_OT_layer_prev);
+
+ WM_operatortype_append(ACTION_OT_previewrange_set);
+ WM_operatortype_append(ACTION_OT_view_all);
+ WM_operatortype_append(ACTION_OT_view_selected);
+ WM_operatortype_append(ACTION_OT_view_frame);
+
+ WM_operatortype_append(ACTION_OT_markers_make_local);
}
void ED_operatormacros_action(void)
{
- wmOperatorType *ot;
- wmOperatorTypeMacro *otmacro;
-
- ot = WM_operatortype_append_macro("ACTION_OT_duplicate_move", "Duplicate",
- "Make a copy of all selected keyframes and move them",
- OPTYPE_UNDO | OPTYPE_REGISTER);
- WM_operatortype_macro_define(ot, "ACTION_OT_duplicate");
- otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_transform");
- RNA_enum_set(otmacro->ptr, "mode", TFM_TIME_DUPLICATE);
- RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF);
+ wmOperatorType *ot;
+ wmOperatorTypeMacro *otmacro;
+
+ ot = WM_operatortype_append_macro("ACTION_OT_duplicate_move",
+ "Duplicate",
+ "Make a copy of all selected keyframes and move them",
+ OPTYPE_UNDO | OPTYPE_REGISTER);
+ WM_operatortype_macro_define(ot, "ACTION_OT_duplicate");
+ otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_transform");
+ RNA_enum_set(otmacro->ptr, "mode", TFM_TIME_DUPLICATE);
+ RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF);
}
/* ************************** registration - keymaps **********************************/
@@ -116,15 +114,15 @@ void ED_operatormacros_action(void)
void action_keymap(wmKeyConfig *keyconf)
{
- /* keymap for all regions */
- WM_keymap_ensure(keyconf, "Dopesheet Generic", SPACE_ACTION, 0);
+ /* keymap for all regions */
+ WM_keymap_ensure(keyconf, "Dopesheet Generic", SPACE_ACTION, 0);
- /* channels */
- /* Channels are not directly handled by the Action Editor module, but are inherited from the Animation module.
- * All the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as these
- * are all used for the Graph-Editor too.
- */
+ /* channels */
+ /* Channels are not directly handled by the Action Editor module, but are inherited from the Animation module.
+ * All the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as these
+ * are all used for the Graph-Editor too.
+ */
- /* keyframes */
- WM_keymap_ensure(keyconf, "Dopesheet", SPACE_ACTION, 0);
+ /* keyframes */
+ WM_keymap_ensure(keyconf, "Dopesheet", SPACE_ACTION, 0);
}
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 872f889e8b4..7499458181e 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -20,7 +20,6 @@
* \ingroup spaction
*/
-
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -63,7 +62,6 @@
#include "action_intern.h"
-
/* ************************************************************************** */
/* KEYFRAMES STUFF */
@@ -82,125 +80,126 @@
*/
static void deselect_action_keys(bAnimContext *ac, short test, short sel)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditData ked = {{NULL}};
- KeyframeEditFunc test_cb, sel_cb;
-
- /* determine type-based settings */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- }
-
- /* filter data */
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* init BezTriple looping data */
- test_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
-
- /* See if we should be selecting or deselecting */
- if (test) {
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- if (ED_gplayer_frame_select_check(ale->data)) {
- sel = SELECT_SUBTRACT;
- break;
- }
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- if (ED_masklayer_frame_select_check(ale->data)) {
- sel = SELECT_SUBTRACT;
- break;
- }
- }
- else {
- if (ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, test_cb, NULL)) {
- sel = SELECT_SUBTRACT;
- break;
- }
- }
- }
- }
-
- /* convert sel to selectmode, and use that to get editor */
- sel_cb = ANIM_editkeyframes_select(sel);
-
- /* Now set the flags */
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_frame_select_set(ale->data, sel);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_masklayer_frame_select_set(ale->data, sel);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL);
- }
- }
-
- /* Cleanup */
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditData ked = {{NULL}};
+ KeyframeEditFunc test_cb, sel_cb;
+
+ /* determine type-based settings */
+ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
+ }
+ else {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
+ ANIMFILTER_NODUPLIS);
+ }
+
+ /* filter data */
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* init BezTriple looping data */
+ test_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
+
+ /* See if we should be selecting or deselecting */
+ if (test) {
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ if (ED_gplayer_frame_select_check(ale->data)) {
+ sel = SELECT_SUBTRACT;
+ break;
+ }
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ if (ED_masklayer_frame_select_check(ale->data)) {
+ sel = SELECT_SUBTRACT;
+ break;
+ }
+ }
+ else {
+ if (ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, test_cb, NULL)) {
+ sel = SELECT_SUBTRACT;
+ break;
+ }
+ }
+ }
+ }
+
+ /* convert sel to selectmode, and use that to get editor */
+ sel_cb = ANIM_editkeyframes_select(sel);
+
+ /* Now set the flags */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gplayer_frame_select_set(ale->data, sel);
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ ED_masklayer_frame_select_set(ale->data, sel);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL);
+ }
+ }
+
+ /* Cleanup */
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_deselectall_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* 'standard' behavior - check if selected, then apply relevant selection */
- const int action = RNA_enum_get(op->ptr, "action");
- switch (action) {
- case SEL_TOGGLE:
- deselect_action_keys(&ac, 1, SELECT_ADD);
- break;
- case SEL_SELECT:
- deselect_action_keys(&ac, 0, SELECT_ADD);
- break;
- case SEL_DESELECT:
- deselect_action_keys(&ac, 0, SELECT_SUBTRACT);
- break;
- case SEL_INVERT:
- deselect_action_keys(&ac, 0, SELECT_INVERT);
- break;
- default:
- BLI_assert(0);
- break;
- }
-
- /* set notifier that keyframe selection have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* 'standard' behavior - check if selected, then apply relevant selection */
+ const int action = RNA_enum_get(op->ptr, "action");
+ switch (action) {
+ case SEL_TOGGLE:
+ deselect_action_keys(&ac, 1, SELECT_ADD);
+ break;
+ case SEL_SELECT:
+ deselect_action_keys(&ac, 0, SELECT_ADD);
+ break;
+ case SEL_DESELECT:
+ deselect_action_keys(&ac, 0, SELECT_SUBTRACT);
+ break;
+ case SEL_INVERT:
+ deselect_action_keys(&ac, 0, SELECT_INVERT);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ /* set notifier that keyframe selection have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+
+ return OPERATOR_FINISHED;
}
void ACTION_OT_select_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select All";
- ot->idname = "ACTION_OT_select_all";
- ot->description = "Toggle selection of all keyframes";
+ /* identifiers */
+ ot->name = "Select All";
+ ot->idname = "ACTION_OT_select_all";
+ ot->description = "Toggle selection of all keyframes";
- /* api callbacks */
- ot->exec = actkeys_deselectall_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_deselectall_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_select_all(ot);
+ /* properties */
+ WM_operator_properties_select_all(ot);
}
/* ******************** Box Select Operator **************************** */
@@ -213,190 +212,183 @@ void ACTION_OT_select_all(wmOperatorType *ot)
/* defines for box_select mode */
enum {
- ACTKEYS_BORDERSEL_ALLKEYS = 0,
- ACTKEYS_BORDERSEL_FRAMERANGE,
- ACTKEYS_BORDERSEL_CHANNELS,
+ ACTKEYS_BORDERSEL_ALLKEYS = 0,
+ ACTKEYS_BORDERSEL_FRAMERANGE,
+ ACTKEYS_BORDERSEL_CHANNELS,
} /*eActKeys_BoxSelect_Mode*/;
-
static void box_select_action(bAnimContext *ac, const rcti rect, short mode, short selectmode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditData ked;
- KeyframeEditFunc ok_cb, select_cb;
- View2D *v2d = &ac->ar->v2d;
- rctf rectf;
- float ymin = 0, ymax = (float)(-ACHANNEL_HEIGHT_HALF(ac));
-
- /* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
- UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin + 2, &rectf.xmin, &rectf.ymin);
- UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax - 2, &rectf.xmax, &rectf.ymax);
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* get beztriple editing/validation funcs */
- select_cb = ANIM_editkeyframes_select(selectmode);
-
- if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS))
- ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
- else
- ok_cb = NULL;
-
- /* init editing data */
- memset(&ked, 0, sizeof(KeyframeEditData));
-
- /* loop over data, doing box select */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* get new vertical minimum extent of channel */
- ymin = ymax - ACHANNEL_STEP(ac);
-
- /* set horizontal range (if applicable) */
- if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
- /* if channel is mapped in NLA, apply correction */
- if (adt) {
- ked.iterflags &= ~(KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP);
- ked.f1 = BKE_nla_tweakedit_remap(adt, rectf.xmin, NLATIME_CONVERT_UNMAP);
- ked.f2 = BKE_nla_tweakedit_remap(adt, rectf.xmax, NLATIME_CONVERT_UNMAP);
- }
- else {
- ked.iterflags |= (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP); /* for summary tracks */
- ked.f1 = rectf.xmin;
- ked.f2 = rectf.xmax;
- }
- }
-
- /* perform vertical suitability check (if applicable) */
- if ((mode == ACTKEYS_BORDERSEL_FRAMERANGE) ||
- !((ymax < rectf.ymin) || (ymin > rectf.ymax)))
- {
- /* loop over data selecting */
- switch (ale->type) {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditData ked;
+ KeyframeEditFunc ok_cb, select_cb;
+ View2D *v2d = &ac->ar->v2d;
+ rctf rectf;
+ float ymin = 0, ymax = (float)(-ACHANNEL_HEIGHT_HALF(ac));
+
+ /* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
+ UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin + 2, &rectf.xmin, &rectf.ymin);
+ UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax - 2, &rectf.xmax, &rectf.ymax);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* get beztriple editing/validation funcs */
+ select_cb = ANIM_editkeyframes_select(selectmode);
+
+ if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS))
+ ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
+ else
+ ok_cb = NULL;
+
+ /* init editing data */
+ memset(&ked, 0, sizeof(KeyframeEditData));
+
+ /* loop over data, doing box select */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* get new vertical minimum extent of channel */
+ ymin = ymax - ACHANNEL_STEP(ac);
+
+ /* set horizontal range (if applicable) */
+ if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
+ /* if channel is mapped in NLA, apply correction */
+ if (adt) {
+ ked.iterflags &= ~(KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP);
+ ked.f1 = BKE_nla_tweakedit_remap(adt, rectf.xmin, NLATIME_CONVERT_UNMAP);
+ ked.f2 = BKE_nla_tweakedit_remap(adt, rectf.xmax, NLATIME_CONVERT_UNMAP);
+ }
+ else {
+ ked.iterflags |= (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP); /* for summary tracks */
+ ked.f1 = rectf.xmin;
+ ked.f2 = rectf.xmax;
+ }
+ }
+
+ /* perform vertical suitability check (if applicable) */
+ if ((mode == ACTKEYS_BORDERSEL_FRAMERANGE) || !((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
+ /* loop over data selecting */
+ switch (ale->type) {
#if 0 /* XXX: Keyframes are not currently shown here */
- case ANIMTYPE_GPDATABLOCK:
- {
- bGPdata *gpd = ale->data;
- bGPDlayer *gpl;
- for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- ED_gplayer_frames_select_box(gpl, rectf.xmin, rectf.xmax, selectmode);
- }
- ale->update |= ANIM_UPDATE_DEPS;
- break;
- }
+ case ANIMTYPE_GPDATABLOCK:
+ {
+ bGPdata *gpd = ale->data;
+ bGPDlayer *gpl;
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ ED_gplayer_frames_select_box(gpl, rectf.xmin, rectf.xmax, selectmode);
+ }
+ ale->update |= ANIM_UPDATE_DEPS;
+ break;
+ }
#endif
- case ANIMTYPE_GPLAYER:
- {
- ED_gplayer_frames_select_box(ale->data, rectf.xmin, rectf.xmax, selectmode);
- ale->update |= ANIM_UPDATE_DEPS;
- break;
- }
- case ANIMTYPE_MASKDATABLOCK:
- {
- Mask *mask = ale->data;
- MaskLayer *masklay;
- for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- ED_masklayer_frames_select_box(masklay, rectf.xmin, rectf.xmax, selectmode);
- }
- break;
- }
- case ANIMTYPE_MASKLAYER:
- {
- ED_masklayer_frames_select_box(ale->data, rectf.xmin, rectf.xmax, selectmode);
- break;
- }
- default:
- {
- ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
- break;
- }
- }
- }
-
- /* set minimum extent to be the maximum of the next channel */
- ymax = ymin;
- }
-
- /* cleanup */
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ case ANIMTYPE_GPLAYER: {
+ ED_gplayer_frames_select_box(ale->data, rectf.xmin, rectf.xmax, selectmode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ break;
+ }
+ case ANIMTYPE_MASKDATABLOCK: {
+ Mask *mask = ale->data;
+ MaskLayer *masklay;
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ ED_masklayer_frames_select_box(masklay, rectf.xmin, rectf.xmax, selectmode);
+ }
+ break;
+ }
+ case ANIMTYPE_MASKLAYER: {
+ ED_masklayer_frames_select_box(ale->data, rectf.xmin, rectf.xmax, selectmode);
+ break;
+ }
+ default: {
+ ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
+ break;
+ }
+ }
+ }
+
+ /* set minimum extent to be the maximum of the next channel */
+ ymax = ymin;
+ }
+
+ /* cleanup */
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_box_select_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- rcti rect;
- short mode = 0;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0) {
- return OPERATOR_CANCELLED;
- }
-
- const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
- const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- deselect_action_keys(&ac, 1, SELECT_SUBTRACT);
- }
-
- /* get settings from operator */
- WM_operator_properties_border_to_rcti(op, &rect);
-
- /* selection 'mode' depends on whether box_select region only matters on one axis */
- if (RNA_boolean_get(op->ptr, "axis_range")) {
- /* mode depends on which axis of the range is larger to determine which axis to use
- * - checking this in region-space is fine, as it's fundamentally still going to be a different rect size
- * - the frame-range select option is favored over the channel one (x over y), as frame-range one is often
- * used for tweaking timing when "blocking", while channels is not that useful...
- */
- if (BLI_rcti_size_x(&rect) >= BLI_rcti_size_y(&rect))
- mode = ACTKEYS_BORDERSEL_FRAMERANGE;
- else
- mode = ACTKEYS_BORDERSEL_CHANNELS;
- }
- else
- mode = ACTKEYS_BORDERSEL_ALLKEYS;
-
- /* apply box_select action */
- box_select_action(&ac, rect, mode, selectmode);
-
- /* set notifier that keyframe selection have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ rcti rect;
+ short mode = 0;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+ const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ deselect_action_keys(&ac, 1, SELECT_SUBTRACT);
+ }
+
+ /* get settings from operator */
+ WM_operator_properties_border_to_rcti(op, &rect);
+
+ /* selection 'mode' depends on whether box_select region only matters on one axis */
+ if (RNA_boolean_get(op->ptr, "axis_range")) {
+ /* mode depends on which axis of the range is larger to determine which axis to use
+ * - checking this in region-space is fine, as it's fundamentally still going to be a different rect size
+ * - the frame-range select option is favored over the channel one (x over y), as frame-range one is often
+ * used for tweaking timing when "blocking", while channels is not that useful...
+ */
+ if (BLI_rcti_size_x(&rect) >= BLI_rcti_size_y(&rect))
+ mode = ACTKEYS_BORDERSEL_FRAMERANGE;
+ else
+ mode = ACTKEYS_BORDERSEL_CHANNELS;
+ }
+ else
+ mode = ACTKEYS_BORDERSEL_ALLKEYS;
+
+ /* apply box_select action */
+ box_select_action(&ac, rect, mode, selectmode);
+
+ /* set notifier that keyframe selection have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+
+ return OPERATOR_FINISHED;
}
void ACTION_OT_select_box(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Box Select";
- ot->idname = "ACTION_OT_select_box";
- ot->description = "Select all keyframes within the specified region";
+ /* identifiers */
+ ot->name = "Box Select";
+ ot->idname = "ACTION_OT_select_box";
+ ot->description = "Select all keyframes within the specified region";
- /* api callbacks */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = actkeys_box_select_exec;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
+ /* api callbacks */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = actkeys_box_select_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
- ot->poll = ED_operator_action_active;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* rna */
- ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
+ /* rna */
+ ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
- /* properties */
- WM_operator_properties_gesture_box(ot);
- WM_operator_properties_select_operation_simple(ot);
+ /* properties */
+ WM_operator_properties_gesture_box(ot);
+ WM_operator_properties_select_operation_simple(ot);
}
/* ******************** Region Select Operators ***************************** */
@@ -405,256 +397,252 @@ void ACTION_OT_select_box(wmOperatorType *ot)
* original Graph Editor implementation of these to do it this way.
*/
-static void region_select_action_keys(bAnimContext *ac, const rctf *rectf_view, short mode, short selectmode, void *data)
+static void region_select_action_keys(
+ bAnimContext *ac, const rctf *rectf_view, short mode, short selectmode, void *data)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditData ked;
- KeyframeEditFunc ok_cb, select_cb;
- View2D *v2d = &ac->ar->v2d;
- rctf rectf, scaled_rectf;
- float ymin = 0, ymax = (float)(-ACHANNEL_HEIGHT_HALF(ac));
-
- /* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
- UI_view2d_region_to_view_rctf(v2d, rectf_view, &rectf);
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* get beztriple editing/validation funcs */
- select_cb = ANIM_editkeyframes_select(selectmode);
- ok_cb = ANIM_editkeyframes_ok(mode);
-
- /* init editing data */
- memset(&ked, 0, sizeof(KeyframeEditData));
- if (mode == BEZT_OK_CHANNEL_LASSO) {
- KeyframeEdit_LassoData *data_lasso = data;
- data_lasso->rectf_scaled = &scaled_rectf;
- ked.data = data_lasso;
- }
- else if (mode == BEZT_OK_CHANNEL_CIRCLE) {
- KeyframeEdit_CircleData *data_circle = data;
- data_circle->rectf_scaled = &scaled_rectf;
- ked.data = data;
- }
- else {
- ked.data = &scaled_rectf;
- }
-
- /* loop over data, doing region select */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* get new vertical minimum extent of channel */
- ymin = ymax - ACHANNEL_STEP(ac);
-
- /* compute midpoint of channel (used for testing if the key is in the region or not) */
- ked.channel_y = ymin + ACHANNEL_HEIGHT_HALF(ac);
-
- /* if channel is mapped in NLA, apply correction
- * - Apply to the bounds being checked, not all the keyframe points,
- * to avoid having scaling everything
- * - Save result to the scaled_rect, which is all that these operators
- * will read from
- */
- if (adt) {
- ked.iterflags &= ~(KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP);
- ked.f1 = BKE_nla_tweakedit_remap(adt, rectf.xmin, NLATIME_CONVERT_UNMAP);
- ked.f2 = BKE_nla_tweakedit_remap(adt, rectf.xmax, NLATIME_CONVERT_UNMAP);
- }
- else {
- ked.iterflags |= (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP); /* for summary tracks */
- ked.f1 = rectf.xmin;
- ked.f2 = rectf.xmax;
- }
-
- /* Update values for scaled_rectf - which is used to compute the mapping in the callbacks
- * NOTE: Since summary tracks need late-binding remapping, the callbacks may overwrite these
- * with the properly remapped ked.f1/f2 values, when needed
- */
- scaled_rectf.xmin = ked.f1;
- scaled_rectf.xmax = ked.f2;
- scaled_rectf.ymin = ymin;
- scaled_rectf.ymax = ymax;
-
- /* perform vertical suitability check (if applicable) */
- if ((mode == ACTKEYS_BORDERSEL_FRAMERANGE) ||
- !((ymax < rectf.ymin) || (ymin > rectf.ymax)))
- {
- /* loop over data selecting */
- switch (ale->type) {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditData ked;
+ KeyframeEditFunc ok_cb, select_cb;
+ View2D *v2d = &ac->ar->v2d;
+ rctf rectf, scaled_rectf;
+ float ymin = 0, ymax = (float)(-ACHANNEL_HEIGHT_HALF(ac));
+
+ /* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
+ UI_view2d_region_to_view_rctf(v2d, rectf_view, &rectf);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* get beztriple editing/validation funcs */
+ select_cb = ANIM_editkeyframes_select(selectmode);
+ ok_cb = ANIM_editkeyframes_ok(mode);
+
+ /* init editing data */
+ memset(&ked, 0, sizeof(KeyframeEditData));
+ if (mode == BEZT_OK_CHANNEL_LASSO) {
+ KeyframeEdit_LassoData *data_lasso = data;
+ data_lasso->rectf_scaled = &scaled_rectf;
+ ked.data = data_lasso;
+ }
+ else if (mode == BEZT_OK_CHANNEL_CIRCLE) {
+ KeyframeEdit_CircleData *data_circle = data;
+ data_circle->rectf_scaled = &scaled_rectf;
+ ked.data = data;
+ }
+ else {
+ ked.data = &scaled_rectf;
+ }
+
+ /* loop over data, doing region select */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* get new vertical minimum extent of channel */
+ ymin = ymax - ACHANNEL_STEP(ac);
+
+ /* compute midpoint of channel (used for testing if the key is in the region or not) */
+ ked.channel_y = ymin + ACHANNEL_HEIGHT_HALF(ac);
+
+ /* if channel is mapped in NLA, apply correction
+ * - Apply to the bounds being checked, not all the keyframe points,
+ * to avoid having scaling everything
+ * - Save result to the scaled_rect, which is all that these operators
+ * will read from
+ */
+ if (adt) {
+ ked.iterflags &= ~(KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP);
+ ked.f1 = BKE_nla_tweakedit_remap(adt, rectf.xmin, NLATIME_CONVERT_UNMAP);
+ ked.f2 = BKE_nla_tweakedit_remap(adt, rectf.xmax, NLATIME_CONVERT_UNMAP);
+ }
+ else {
+ ked.iterflags |= (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP); /* for summary tracks */
+ ked.f1 = rectf.xmin;
+ ked.f2 = rectf.xmax;
+ }
+
+ /* Update values for scaled_rectf - which is used to compute the mapping in the callbacks
+ * NOTE: Since summary tracks need late-binding remapping, the callbacks may overwrite these
+ * with the properly remapped ked.f1/f2 values, when needed
+ */
+ scaled_rectf.xmin = ked.f1;
+ scaled_rectf.xmax = ked.f2;
+ scaled_rectf.ymin = ymin;
+ scaled_rectf.ymax = ymax;
+
+ /* perform vertical suitability check (if applicable) */
+ if ((mode == ACTKEYS_BORDERSEL_FRAMERANGE) || !((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
+ /* loop over data selecting */
+ switch (ale->type) {
#if 0 /* XXX: Keyframes are not currently shown here */
- case ANIMTYPE_GPDATABLOCK:
- {
- bGPdata *gpd = ale->data;
- bGPDlayer *gpl;
- for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- ED_gplayer_frames_select_region(&ked, ale->data, mode, selectmode);
- }
- break;
- }
+ case ANIMTYPE_GPDATABLOCK:
+ {
+ bGPdata *gpd = ale->data;
+ bGPDlayer *gpl;
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ ED_gplayer_frames_select_region(&ked, ale->data, mode, selectmode);
+ }
+ break;
+ }
#endif
- case ANIMTYPE_GPLAYER:
- {
- ED_gplayer_frames_select_region(&ked, ale->data, mode, selectmode);
- ale->update |= ANIM_UPDATE_DEPS;
- break;
- }
- case ANIMTYPE_MASKDATABLOCK:
- {
- Mask *mask = ale->data;
- MaskLayer *masklay;
- for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- ED_masklayer_frames_select_region(&ked, masklay, mode, selectmode);
- }
- break;
- }
- case ANIMTYPE_MASKLAYER:
- {
- ED_masklayer_frames_select_region(&ked, ale->data, mode, selectmode);
- break;
- }
- default:
- ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
- break;
- }
- }
-
- /* set minimum extent to be the maximum of the next channel */
- ymax = ymin;
- }
-
- /* cleanup */
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ case ANIMTYPE_GPLAYER: {
+ ED_gplayer_frames_select_region(&ked, ale->data, mode, selectmode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ break;
+ }
+ case ANIMTYPE_MASKDATABLOCK: {
+ Mask *mask = ale->data;
+ MaskLayer *masklay;
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ ED_masklayer_frames_select_region(&ked, masklay, mode, selectmode);
+ }
+ break;
+ }
+ case ANIMTYPE_MASKLAYER: {
+ ED_masklayer_frames_select_region(&ked, ale->data, mode, selectmode);
+ break;
+ }
+ default:
+ ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
+ break;
+ }
+ }
+
+ /* set minimum extent to be the maximum of the next channel */
+ ymax = ymin;
+ }
+
+ /* cleanup */
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ----------------------------------- */
static int actkeys_lassoselect_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
+ bAnimContext ac;
- KeyframeEdit_LassoData data_lasso;
- rcti rect;
- rctf rect_fl;
+ KeyframeEdit_LassoData data_lasso;
+ rcti rect;
+ rctf rect_fl;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- data_lasso.rectf_view = &rect_fl;
- data_lasso.mcords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcords_tot);
- if (data_lasso.mcords == NULL)
- return OPERATOR_CANCELLED;
+ data_lasso.rectf_view = &rect_fl;
+ data_lasso.mcords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcords_tot);
+ if (data_lasso.mcords == NULL)
+ return OPERATOR_CANCELLED;
- const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
- const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- deselect_action_keys(&ac, 1, SELECT_SUBTRACT);
- }
+ const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+ const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ deselect_action_keys(&ac, 1, SELECT_SUBTRACT);
+ }
- /* get settings from operator */
- BLI_lasso_boundbox(&rect, data_lasso.mcords, data_lasso.mcords_tot);
- BLI_rctf_rcti_copy(&rect_fl, &rect);
+ /* get settings from operator */
+ BLI_lasso_boundbox(&rect, data_lasso.mcords, data_lasso.mcords_tot);
+ BLI_rctf_rcti_copy(&rect_fl, &rect);
- /* apply box_select action */
- region_select_action_keys(&ac, &rect_fl, BEZT_OK_CHANNEL_LASSO, selectmode, &data_lasso);
+ /* apply box_select action */
+ region_select_action_keys(&ac, &rect_fl, BEZT_OK_CHANNEL_LASSO, selectmode, &data_lasso);
- MEM_freeN((void *)data_lasso.mcords);
+ MEM_freeN((void *)data_lasso.mcords);
- /* send notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* send notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_select_lasso(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Lasso Select";
- ot->description = "Select keyframe points using lasso selection";
- ot->idname = "ACTION_OT_select_lasso";
-
- /* api callbacks */
- ot->invoke = WM_gesture_lasso_invoke;
- ot->modal = WM_gesture_lasso_modal;
- ot->exec = actkeys_lassoselect_exec;
- ot->poll = ED_operator_action_active;
- ot->cancel = WM_gesture_lasso_cancel;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-
- /* properties */
- WM_operator_properties_gesture_lasso(ot);
- WM_operator_properties_select_operation_simple(ot);
+ /* identifiers */
+ ot->name = "Lasso Select";
+ ot->description = "Select keyframe points using lasso selection";
+ ot->idname = "ACTION_OT_select_lasso";
+
+ /* api callbacks */
+ ot->invoke = WM_gesture_lasso_invoke;
+ ot->modal = WM_gesture_lasso_modal;
+ ot->exec = actkeys_lassoselect_exec;
+ ot->poll = ED_operator_action_active;
+ ot->cancel = WM_gesture_lasso_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_gesture_lasso(ot);
+ WM_operator_properties_select_operation_simple(ot);
}
/* ------------------- */
static int action_circle_select_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
+ bAnimContext ac;
- KeyframeEdit_CircleData data = {0};
- rctf rect_fl;
+ KeyframeEdit_CircleData data = {0};
+ rctf rect_fl;
- float x = RNA_int_get(op->ptr, "x");
- float y = RNA_int_get(op->ptr, "y");
- float radius = RNA_int_get(op->ptr, "radius");
+ float x = RNA_int_get(op->ptr, "x");
+ float y = RNA_int_get(op->ptr, "y");
+ float radius = RNA_int_get(op->ptr, "radius");
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- const eSelectOp sel_op = ED_select_op_modal(
- RNA_enum_get(op->ptr, "mode"), WM_gesture_is_modal_first(op->customdata));
- const short selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- deselect_action_keys(&ac, 0, SELECT_SUBTRACT);
- }
+ const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"),
+ WM_gesture_is_modal_first(op->customdata));
+ const short selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ deselect_action_keys(&ac, 0, SELECT_SUBTRACT);
+ }
- data.mval[0] = x;
- data.mval[1] = y;
- data.radius_squared = radius * radius;
- data.rectf_view = &rect_fl;
+ data.mval[0] = x;
+ data.mval[1] = y;
+ data.radius_squared = radius * radius;
+ data.rectf_view = &rect_fl;
- rect_fl.xmin = x - radius;
- rect_fl.xmax = x + radius;
- rect_fl.ymin = y - radius;
- rect_fl.ymax = y + radius;
+ rect_fl.xmin = x - radius;
+ rect_fl.xmax = x + radius;
+ rect_fl.ymin = y - radius;
+ rect_fl.ymax = y + radius;
- /* apply region select action */
- region_select_action_keys(&ac, &rect_fl, BEZT_OK_CHANNEL_CIRCLE, selectmode, &data);
+ /* apply region select action */
+ region_select_action_keys(&ac, &rect_fl, BEZT_OK_CHANNEL_CIRCLE, selectmode, &data);
- /* send notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* send notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_select_circle(wmOperatorType *ot)
{
- ot->name = "Circle Select";
- ot->description = "Select keyframe points using circle selection";
- ot->idname = "ACTION_OT_select_circle";
-
- ot->invoke = WM_gesture_circle_invoke;
- ot->modal = WM_gesture_circle_modal;
- ot->exec = action_circle_select_exec;
- ot->poll = ED_operator_action_active;
- ot->cancel = WM_gesture_circle_cancel;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-
- /* properties */
- WM_operator_properties_gesture_circle(ot);
- WM_operator_properties_select_operation_simple(ot);
+ ot->name = "Circle Select";
+ ot->description = "Select keyframe points using circle selection";
+ ot->idname = "ACTION_OT_select_circle";
+
+ ot->invoke = WM_gesture_circle_invoke;
+ ot->modal = WM_gesture_circle_modal;
+ ot->exec = action_circle_select_exec;
+ ot->poll = ED_operator_action_active;
+ ot->cancel = WM_gesture_circle_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_gesture_circle(ot);
+ WM_operator_properties_select_operation_simple(ot);
}
/* ******************** Column Select Operator **************************** */
@@ -667,11 +655,15 @@ void ACTION_OT_select_circle(wmOperatorType *ot)
/* defines for column-select mode */
static const EnumPropertyItem prop_column_select_types[] = {
- {ACTKEYS_COLUMNSEL_KEYS, "KEYS", 0, "On Selected Keyframes", ""},
- {ACTKEYS_COLUMNSEL_CFRA, "CFRA", 0, "On Current Frame", ""},
- {ACTKEYS_COLUMNSEL_MARKERS_COLUMN, "MARKERS_COLUMN", 0, "On Selected Markers", ""},
- {ACTKEYS_COLUMNSEL_MARKERS_BETWEEN, "MARKERS_BETWEEN", 0, "Between Min/Max Selected Markers", ""},
- {0, NULL, 0, NULL, NULL},
+ {ACTKEYS_COLUMNSEL_KEYS, "KEYS", 0, "On Selected Keyframes", ""},
+ {ACTKEYS_COLUMNSEL_CFRA, "CFRA", 0, "On Current Frame", ""},
+ {ACTKEYS_COLUMNSEL_MARKERS_COLUMN, "MARKERS_COLUMN", 0, "On Selected Markers", ""},
+ {ACTKEYS_COLUMNSEL_MARKERS_BETWEEN,
+ "MARKERS_BETWEEN",
+ 0,
+ "Between Min/Max Selected Markers",
+ ""},
+ {0, NULL, 0, NULL, NULL},
};
/* ------------------- */
@@ -681,248 +673,249 @@ static const EnumPropertyItem prop_column_select_types[] = {
* should de-duplicate - campbell */
static void markers_selectkeys_between(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditFunc ok_cb, select_cb;
- KeyframeEditData ked = {{NULL}};
- float min, max;
-
- /* get extreme markers */
- ED_markers_get_minmax(ac->markers, 1, &min, &max);
- min -= 0.5f;
- max += 0.5f;
-
- /* get editing funcs + data */
- ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
- select_cb = ANIM_editkeyframes_select(SELECT_ADD);
-
- ked.f1 = min;
- ked.f2 = max;
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* select keys in-between */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
- }
- else if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_frames_select_box(ale->data, min, max, SELECT_ADD);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_masklayer_frames_select_box(ale->data, min, max, SELECT_ADD);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- }
- }
-
- /* Cleanup */
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditFunc ok_cb, select_cb;
+ KeyframeEditData ked = {{NULL}};
+ float min, max;
+
+ /* get extreme markers */
+ ED_markers_get_minmax(ac->markers, 1, &min, &max);
+ min -= 0.5f;
+ max += 0.5f;
+
+ /* get editing funcs + data */
+ ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
+ select_cb = ANIM_editkeyframes_select(SELECT_ADD);
+
+ ked.f1 = min;
+ ked.f2 = max;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* select keys in-between */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ }
+ else if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gplayer_frames_select_box(ale->data, min, max, SELECT_ADD);
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ ED_masklayer_frames_select_box(ale->data, min, max, SELECT_ADD);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+ }
+
+ /* Cleanup */
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
-
/* Selects all visible keyframes in the same frames as the specified elements */
static void columnselect_action_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- Scene *scene = ac->scene;
- CfraElem *ce;
- KeyframeEditFunc select_cb, ok_cb;
- KeyframeEditData ked = {{NULL}};
-
- /* build list of columns */
- switch (mode) {
- case ACTKEYS_COLUMNSEL_KEYS: /* list of selected keys */
- if (ac->datatype == ANIMCONT_GPENCIL) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next)
- ED_gplayer_make_cfra_list(ale->data, &ked.list, 1);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next)
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
- }
- ANIM_animdata_freelist(&anim_data);
- break;
-
- case ACTKEYS_COLUMNSEL_CFRA: /* current frame */
- /* make a single CfraElem for storing this */
- ce = MEM_callocN(sizeof(CfraElem), "cfraElem");
- BLI_addtail(&ked.list, ce);
-
- ce->cfra = (float)CFRA;
- break;
-
- case ACTKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */
- ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT);
- break;
-
- default: /* invalid option */
- return;
- }
-
- /* set up BezTriple edit callbacks */
- select_cb = ANIM_editkeyframes_select(SELECT_ADD);
- ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
-
- /* loop through all of the keys and select additional keyframes
- * based on the keys found to be selected above
- */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
- else
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* loop over cfraelems (stored in the KeyframeEditData->list)
- * - we need to do this here, as we can apply fewer NLA-mapping conversions
- */
- for (ce = ked.list.first; ce; ce = ce->next) {
- /* set frame for validation callback to refer to */
- if (adt)
- ked.f1 = BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP);
- else
- ked.f1 = ce->cfra;
-
- /* select elements with frame number matching cfraelem */
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frame(ale->data, ce->cfra, SELECT_ADD);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frame(ale->data, ce->cfra, SELECT_ADD);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- }
- }
- }
-
- /* free elements */
- BLI_freelistN(&ked.list);
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ Scene *scene = ac->scene;
+ CfraElem *ce;
+ KeyframeEditFunc select_cb, ok_cb;
+ KeyframeEditData ked = {{NULL}};
+
+ /* build list of columns */
+ switch (mode) {
+ case ACTKEYS_COLUMNSEL_KEYS: /* list of selected keys */
+ if (ac->datatype == ANIMCONT_GPENCIL) {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next)
+ ED_gplayer_make_cfra_list(ale->data, &ked.list, 1);
+ }
+ else {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next)
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
+ }
+ ANIM_animdata_freelist(&anim_data);
+ break;
+
+ case ACTKEYS_COLUMNSEL_CFRA: /* current frame */
+ /* make a single CfraElem for storing this */
+ ce = MEM_callocN(sizeof(CfraElem), "cfraElem");
+ BLI_addtail(&ked.list, ce);
+
+ ce->cfra = (float)CFRA;
+ break;
+
+ case ACTKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */
+ ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT);
+ break;
+
+ default: /* invalid option */
+ return;
+ }
+
+ /* set up BezTriple edit callbacks */
+ select_cb = ANIM_editkeyframes_select(SELECT_ADD);
+ ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
+
+ /* loop through all of the keys and select additional keyframes
+ * based on the keys found to be selected above
+ */
+ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
+ else
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* loop over cfraelems (stored in the KeyframeEditData->list)
+ * - we need to do this here, as we can apply fewer NLA-mapping conversions
+ */
+ for (ce = ked.list.first; ce; ce = ce->next) {
+ /* set frame for validation callback to refer to */
+ if (adt)
+ ked.f1 = BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP);
+ else
+ ked.f1 = ce->cfra;
+
+ /* select elements with frame number matching cfraelem */
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gpencil_select_frame(ale->data, ce->cfra, SELECT_ADD);
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ ED_mask_select_frame(ale->data, ce->cfra, SELECT_ADD);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+ }
+ }
+
+ /* free elements */
+ BLI_freelistN(&ked.list);
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int actkeys_columnselect_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* action to take depends on the mode */
- mode = RNA_enum_get(op->ptr, "mode");
+ /* action to take depends on the mode */
+ mode = RNA_enum_get(op->ptr, "mode");
- if (mode == ACTKEYS_COLUMNSEL_MARKERS_BETWEEN)
- markers_selectkeys_between(&ac);
- else
- columnselect_action_keys(&ac, mode);
+ if (mode == ACTKEYS_COLUMNSEL_MARKERS_BETWEEN)
+ markers_selectkeys_between(&ac);
+ else
+ columnselect_action_keys(&ac, mode);
- /* set notifier that keyframe selection have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_select_column(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select All";
- ot->idname = "ACTION_OT_select_column";
- ot->description = "Select all keyframes on the specified frame(s)";
+ /* identifiers */
+ ot->name = "Select All";
+ ot->idname = "ACTION_OT_select_column";
+ ot->description = "Select all keyframes on the specified frame(s)";
- /* api callbacks */
- ot->exec = actkeys_columnselect_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_columnselect_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", "");
+ /* props */
+ ot->prop = RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", "");
}
/* ******************** Select Linked Operator *********************** */
static int actkeys_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
- KeyframeEditFunc sel_cb = ANIM_editkeyframes_select(SELECT_ADD);
+ KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
+ KeyframeEditFunc sel_cb = ANIM_editkeyframes_select(SELECT_ADD);
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* loop through all of the keys and select additional keyframes based on these */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* loop through all of the keys and select additional keyframes based on these */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
- /* check if anything selected? */
- if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, ok_cb, NULL)) {
- /* select every keyframe in this curve then */
- ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL);
- }
- }
+ /* check if anything selected? */
+ if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, ok_cb, NULL)) {
+ /* select every keyframe in this curve then */
+ ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL);
+ }
+ }
- /* Cleanup */
- ANIM_animdata_freelist(&anim_data);
+ /* Cleanup */
+ ANIM_animdata_freelist(&anim_data);
- /* set notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_select_linked(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Linked";
- ot->idname = "ACTION_OT_select_linked";
- ot->description = "Select keyframes occurring in the same F-Curves as selected ones";
+ /* identifiers */
+ ot->name = "Select Linked";
+ ot->idname = "ACTION_OT_select_linked";
+ ot->description = "Select keyframes occurring in the same F-Curves as selected ones";
- /* api callbacks */
- ot->exec = actkeys_select_linked_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_select_linked_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Select More/Less Operators *********************** */
@@ -930,110 +923,110 @@ void ACTION_OT_select_linked(wmOperatorType *ot)
/* Common code to perform selection */
static void select_moreless_action_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditData ked = {{NULL}};
- KeyframeEditFunc build_cb;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ KeyframeEditData ked = {{NULL}};
+ KeyframeEditFunc build_cb;
- /* init selmap building data */
- build_cb = ANIM_editkeyframes_buildselmap(mode);
+ /* init selmap building data */
+ build_cb = ANIM_editkeyframes_buildselmap(mode);
- /* loop through all of the keys and select additional keyframes based on these */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* loop through all of the keys and select additional keyframes based on these */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
- /* only continue if F-Curve has keyframes */
- if (fcu->bezt == NULL)
- continue;
+ /* only continue if F-Curve has keyframes */
+ if (fcu->bezt == NULL)
+ continue;
- /* build up map of whether F-Curve's keyframes should be selected or not */
- ked.data = MEM_callocN(fcu->totvert, "selmap actEdit more");
- ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, build_cb, NULL);
+ /* build up map of whether F-Curve's keyframes should be selected or not */
+ ked.data = MEM_callocN(fcu->totvert, "selmap actEdit more");
+ ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, build_cb, NULL);
- /* based on this map, adjust the selection status of the keyframes */
- ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_selmap_flush, NULL);
+ /* based on this map, adjust the selection status of the keyframes */
+ ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_selmap_flush, NULL);
- /* free the selmap used here */
- MEM_freeN(ked.data);
- ked.data = NULL;
- }
+ /* free the selmap used here */
+ MEM_freeN(ked.data);
+ ked.data = NULL;
+ }
- /* Cleanup */
- ANIM_animdata_freelist(&anim_data);
+ /* Cleanup */
+ ANIM_animdata_freelist(&anim_data);
}
/* ----------------- */
static int actkeys_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* perform select changes */
- select_moreless_action_keys(&ac, SELMAP_MORE);
+ /* perform select changes */
+ select_moreless_action_keys(&ac, SELMAP_MORE);
- /* set notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_select_more(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select More";
- ot->idname = "ACTION_OT_select_more";
- ot->description = "Select keyframes beside already selected ones";
+ /* identifiers */
+ ot->name = "Select More";
+ ot->idname = "ACTION_OT_select_more";
+ ot->description = "Select keyframes beside already selected ones";
- /* api callbacks */
- ot->exec = actkeys_select_more_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_select_more_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ----------------- */
static int actkeys_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* perform select changes */
- select_moreless_action_keys(&ac, SELMAP_LESS);
+ /* perform select changes */
+ select_moreless_action_keys(&ac, SELMAP_LESS);
- /* set notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ACTION_OT_select_less(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Less";
- ot->idname = "ACTION_OT_select_less";
- ot->description = "Deselect keyframes on ends of selection islands";
+ /* identifiers */
+ ot->name = "Select Less";
+ ot->idname = "ACTION_OT_select_less";
+ ot->description = "Deselect keyframes on ends of selection islands";
- /* api callbacks */
- ot->exec = actkeys_select_less_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->exec = actkeys_select_less_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Select Left/Right Operator ************************* */
@@ -1041,186 +1034,187 @@ void ACTION_OT_select_less(wmOperatorType *ot)
/* defines for left-right select tool */
static const EnumPropertyItem prop_actkeys_leftright_select_types[] = {
- {ACTKEYS_LRSEL_TEST, "CHECK", 0, "Check if Select Left or Right", ""},
- {ACTKEYS_LRSEL_LEFT, "LEFT", 0, "Before current frame", ""},
- {ACTKEYS_LRSEL_RIGHT, "RIGHT", 0, "After current frame", ""},
- {0, NULL, 0, NULL, NULL},
+ {ACTKEYS_LRSEL_TEST, "CHECK", 0, "Check if Select Left or Right", ""},
+ {ACTKEYS_LRSEL_LEFT, "LEFT", 0, "Before current frame", ""},
+ {ACTKEYS_LRSEL_RIGHT, "RIGHT", 0, "After current frame", ""},
+ {0, NULL, 0, NULL, NULL},
};
/* --------------------------------- */
static void actkeys_select_leftright(bAnimContext *ac, short leftright, short select_mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditFunc ok_cb, select_cb;
- KeyframeEditData ked = {{NULL}};
- Scene *scene = ac->scene;
-
- /* if select mode is replace, deselect all keyframes (and channels) first */
- if (select_mode == SELECT_REPLACE) {
- select_mode = SELECT_ADD;
-
- /* - deselect all other keyframes, so that just the newly selected remain
- * - channels aren't deselected, since we don't re-select any as a consequence
- */
- deselect_action_keys(ac, 0, SELECT_SUBTRACT);
- }
-
- /* set callbacks and editing data */
- ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
- select_cb = ANIM_editkeyframes_select(select_mode);
-
- if (leftright == ACTKEYS_LRSEL_LEFT) {
- ked.f1 = MINAFRAMEF;
- ked.f2 = (float)(CFRA + 0.1f);
- }
- else {
- ked.f1 = (float)(CFRA - 0.1f);
- ked.f2 = MAXFRAMEF;
- }
-
- /* filter data */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- }
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* select keys */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
- }
- else if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_masklayer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- }
- }
-
- /* Sync marker support */
- if (select_mode == SELECT_ADD) {
- SpaceAction *saction = (SpaceAction *)ac->sl;
-
- if ((saction) && (saction->flag & SACTION_MARKERS_MOVE)) {
- ListBase *markers = ED_animcontext_get_markers(ac);
- TimeMarker *marker;
-
- for (marker = markers->first; marker; marker = marker->next) {
- if (((leftright == ACTKEYS_LRSEL_LEFT) && (marker->frame < CFRA)) ||
- ((leftright == ACTKEYS_LRSEL_RIGHT) && (marker->frame >= CFRA)))
- {
- marker->flag |= SELECT;
- }
- else {
- marker->flag &= ~SELECT;
- }
- }
- }
- }
-
- /* Cleanup */
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditFunc ok_cb, select_cb;
+ KeyframeEditData ked = {{NULL}};
+ Scene *scene = ac->scene;
+
+ /* if select mode is replace, deselect all keyframes (and channels) first */
+ if (select_mode == SELECT_REPLACE) {
+ select_mode = SELECT_ADD;
+
+ /* - deselect all other keyframes, so that just the newly selected remain
+ * - channels aren't deselected, since we don't re-select any as a consequence
+ */
+ deselect_action_keys(ac, 0, SELECT_SUBTRACT);
+ }
+
+ /* set callbacks and editing data */
+ ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
+ select_cb = ANIM_editkeyframes_select(select_mode);
+
+ if (leftright == ACTKEYS_LRSEL_LEFT) {
+ ked.f1 = MINAFRAMEF;
+ ked.f2 = (float)(CFRA + 0.1f);
+ }
+ else {
+ ked.f1 = (float)(CFRA - 0.1f);
+ ked.f2 = MAXFRAMEF;
+ }
+
+ /* filter data */
+ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
+ }
+ else {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
+ ANIMFILTER_NODUPLIS);
+ }
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* select keys */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ }
+ else if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gplayer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ ED_masklayer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+ }
+
+ /* Sync marker support */
+ if (select_mode == SELECT_ADD) {
+ SpaceAction *saction = (SpaceAction *)ac->sl;
+
+ if ((saction) && (saction->flag & SACTION_MARKERS_MOVE)) {
+ ListBase *markers = ED_animcontext_get_markers(ac);
+ TimeMarker *marker;
+
+ for (marker = markers->first; marker; marker = marker->next) {
+ if (((leftright == ACTKEYS_LRSEL_LEFT) && (marker->frame < CFRA)) ||
+ ((leftright == ACTKEYS_LRSEL_RIGHT) && (marker->frame >= CFRA))) {
+ marker->flag |= SELECT;
+ }
+ else {
+ marker->flag &= ~SELECT;
+ }
+ }
+ }
+ }
+
+ /* Cleanup */
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ----------------- */
static int actkeys_select_leftright_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short leftright = RNA_enum_get(op->ptr, "mode");
- short selectmode;
+ bAnimContext ac;
+ short leftright = RNA_enum_get(op->ptr, "mode");
+ short selectmode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* select mode is either replace (deselect all, then add) or add/extend */
- if (RNA_boolean_get(op->ptr, "extend"))
- selectmode = SELECT_INVERT;
- else
- selectmode = SELECT_REPLACE;
+ /* select mode is either replace (deselect all, then add) or add/extend */
+ if (RNA_boolean_get(op->ptr, "extend"))
+ selectmode = SELECT_INVERT;
+ else
+ selectmode = SELECT_REPLACE;
- /* if "test" mode is set, we don't have any info to set this with */
- if (leftright == ACTKEYS_LRSEL_TEST)
- return OPERATOR_CANCELLED;
+ /* if "test" mode is set, we don't have any info to set this with */
+ if (leftright == ACTKEYS_LRSEL_TEST)
+ return OPERATOR_CANCELLED;
- /* do the selecting now */
- actkeys_select_leftright(&ac, leftright, selectmode);
+ /* do the selecting now */
+ actkeys_select_leftright(&ac, leftright, selectmode);
- /* set notifier that keyframe selection (and channels too) have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection (and channels too) have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static int actkeys_select_leftright_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bAnimContext ac;
- short leftright = RNA_enum_get(op->ptr, "mode");
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* handle mode-based testing */
- if (leftright == ACTKEYS_LRSEL_TEST) {
- Scene *scene = ac.scene;
- ARegion *ar = ac.ar;
- View2D *v2d = &ar->v2d;
- float x;
-
- /* determine which side of the current frame mouse is on */
- x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
- if (x < CFRA)
- RNA_enum_set(op->ptr, "mode", ACTKEYS_LRSEL_LEFT);
- else
- RNA_enum_set(op->ptr, "mode", ACTKEYS_LRSEL_RIGHT);
- }
-
- /* perform selection */
- return actkeys_select_leftright_exec(C, op);
+ bAnimContext ac;
+ short leftright = RNA_enum_get(op->ptr, "mode");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* handle mode-based testing */
+ if (leftright == ACTKEYS_LRSEL_TEST) {
+ Scene *scene = ac.scene;
+ ARegion *ar = ac.ar;
+ View2D *v2d = &ar->v2d;
+ float x;
+
+ /* determine which side of the current frame mouse is on */
+ x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
+ if (x < CFRA)
+ RNA_enum_set(op->ptr, "mode", ACTKEYS_LRSEL_LEFT);
+ else
+ RNA_enum_set(op->ptr, "mode", ACTKEYS_LRSEL_RIGHT);
+ }
+
+ /* perform selection */
+ return actkeys_select_leftright_exec(C, op);
}
void ACTION_OT_select_leftright(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Select Left/Right";
- ot->idname = "ACTION_OT_select_leftright";
- ot->description = "Select keyframes to the left or the right of the current frame";
+ /* identifiers */
+ ot->name = "Select Left/Right";
+ ot->idname = "ACTION_OT_select_leftright";
+ ot->description = "Select keyframes to the left or the right of the current frame";
- /* api callbacks */
- ot->invoke = actkeys_select_leftright_invoke;
- ot->exec = actkeys_select_leftright_exec;
- ot->poll = ED_operator_action_active;
+ /* api callbacks */
+ ot->invoke = actkeys_select_leftright_invoke;
+ ot->exec = actkeys_select_leftright_exec;
+ ot->poll = ED_operator_action_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "mode", prop_actkeys_leftright_select_types, ACTKEYS_LRSEL_TEST, "Mode", "");
- RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+ /* properties */
+ ot->prop = RNA_def_enum(
+ ot->srna, "mode", prop_actkeys_leftright_select_types, ACTKEYS_LRSEL_TEST, "Mode", "");
+ RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ******************** Mouse-Click Select Operator *********************** */
@@ -1237,52 +1231,55 @@ void ACTION_OT_select_leftright(wmOperatorType *ot)
/* ------------------- */
/* option 1) select keyframe directly under mouse */
-static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short select_mode, float selx)
+static void actkeys_mselect_single(bAnimContext *ac,
+ bAnimListElem *ale,
+ short select_mode,
+ float selx)
{
- KeyframeEditData ked = {{NULL}};
- KeyframeEditFunc select_cb, ok_cb;
-
- /* get functions for selecting keyframes */
- select_cb = ANIM_editkeyframes_select(select_mode);
- ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
- ked.f1 = selx;
- ked.iterflags |= KED_F1_NLA_UNMAP;
-
- /* select the nominated keyframe on the given frame */
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frame(ale->data, selx, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frame(ale->data, selx, select_mode);
- }
- else {
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) &&
- (ale->type == ANIMTYPE_SUMMARY) && (ale->datatype == ALE_ALL))
- {
- ListBase anim_data = {NULL, NULL};
- int filter;
-
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frame(ale->data, selx, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frame(ale->data, selx, select_mode);
- }
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
- }
- else {
- ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
- }
- }
+ KeyframeEditData ked = {{NULL}};
+ KeyframeEditFunc select_cb, ok_cb;
+
+ /* get functions for selecting keyframes */
+ select_cb = ANIM_editkeyframes_select(select_mode);
+ ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
+ ked.f1 = selx;
+ ked.iterflags |= KED_F1_NLA_UNMAP;
+
+ /* select the nominated keyframe on the given frame */
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gpencil_select_frame(ale->data, selx, select_mode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ ED_mask_select_frame(ale->data, selx, select_mode);
+ }
+ else {
+ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) && (ale->type == ANIMTYPE_SUMMARY) &&
+ (ale->datatype == ALE_ALL)) {
+ ListBase anim_data = {NULL, NULL};
+ int filter;
+
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gpencil_select_frame(ale->data, selx, select_mode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ ED_mask_select_frame(ale->data, selx, select_mode);
+ }
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
+ }
+ else {
+ ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
+ }
+ }
}
/* Option 2) Selects all the keyframes on either side of the current frame
@@ -1292,390 +1289,402 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s
/* Option 3) Selects all visible keyframes in the same frame as the mouse click */
static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float selx)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditFunc select_cb, ok_cb;
- KeyframeEditData ked = {{NULL}};
-
- /* set up BezTriple edit callbacks */
- select_cb = ANIM_editkeyframes_select(select_mode);
- ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
-
- /* loop through all of the keys and select additional keyframes
- * based on the keys found to be selected above
- */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
- }
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* set frame for validation callback to refer to */
- if (adt)
- ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
- else
- ked.f1 = selx;
-
- /* select elements with frame number matching cfra */
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frame(ale->key_data, selx, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frame(ale->key_data, selx, select_mode);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- }
- }
-
- /* free elements */
- BLI_freelistN(&ked.list);
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditFunc select_cb, ok_cb;
+ KeyframeEditData ked = {{NULL}};
+
+ /* set up BezTriple edit callbacks */
+ select_cb = ANIM_editkeyframes_select(select_mode);
+ ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
+
+ /* loop through all of the keys and select additional keyframes
+ * based on the keys found to be selected above
+ */
+ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
+ ANIMFILTER_NODUPLIS);
+ }
+ else {
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
+ }
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* set frame for validation callback to refer to */
+ if (adt)
+ ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
+ else
+ ked.f1 = selx;
+
+ /* select elements with frame number matching cfra */
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gpencil_select_frame(ale->key_data, selx, select_mode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ ED_mask_select_frame(ale->key_data, selx, select_mode);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+ }
+
+ /* free elements */
+ BLI_freelistN(&ked.list);
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* option 4) select all keyframes in same channel */
static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, short select_mode)
{
- KeyframeEditFunc select_cb;
-
- /* get functions for selecting keyframes */
- select_cb = ANIM_editkeyframes_select(select_mode);
-
- /* select all keyframes in this channel */
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frames(ale->data, select_mode);
- ale->update = ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frames(ale->data, select_mode);
- }
- else {
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) &&
- (ale->type == ANIMTYPE_SUMMARY) && (ale->datatype == ALE_ALL))
- {
- ListBase anim_data = {NULL, NULL};
- int filter;
-
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frames(ale->data, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frames(ale->data, select_mode);
- }
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
- }
- else {
- ANIM_animchannel_keyframes_loop(NULL, ac->ads, ale, NULL, select_cb, NULL);
- }
- }
+ KeyframeEditFunc select_cb;
+
+ /* get functions for selecting keyframes */
+ select_cb = ANIM_editkeyframes_select(select_mode);
+
+ /* select all keyframes in this channel */
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gpencil_select_frames(ale->data, select_mode);
+ ale->update = ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ ED_mask_select_frames(ale->data, select_mode);
+ }
+ else {
+ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) && (ale->type == ANIMTYPE_SUMMARY) &&
+ (ale->datatype == ALE_ALL)) {
+ ListBase anim_data = {NULL, NULL};
+ int filter;
+
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gpencil_select_frames(ale->data, select_mode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ ED_mask_select_frames(ale->data, select_mode);
+ }
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
+ }
+ else {
+ ANIM_animchannel_keyframes_loop(NULL, ac->ads, ale, NULL, select_cb, NULL);
+ }
+ }
}
/* ------------------- */
-static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_mode, bool column, bool same_channel)
+static void mouse_action_keys(
+ bAnimContext *ac, const int mval[2], short select_mode, bool column, bool same_channel)
{
- ListBase anim_data = {NULL, NULL};
- DLRBT_Tree anim_keys;
- bAnimListElem *ale;
- int filter;
-
- View2D *v2d = &ac->ar->v2d;
- bDopeSheet *ads = NULL;
- int channel_index;
- bool found = false;
- float frame = 0.0f; /* frame of keyframe under mouse - NLA corrections not applied/included */
- float selx = 0.0f; /* frame of keyframe under mouse */
- float key_hsize;
- float x, y;
- rctf rectf;
-
- /* get dopesheet info */
- if (ELEM(ac->datatype, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE))
- ads = ac->data;
-
- /* use View2D to determine the index of the channel (i.e a row in the list) where keyframe was */
- UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
- UI_view2d_listview_view_to_cell(v2d, 0, ACHANNEL_STEP(ac), 0, (float)ACHANNEL_HEIGHT_HALF(ac), x, y, NULL, &channel_index);
-
- /* x-range to check is +/- 7px for standard keyframe under standard dpi/y-scale (in screen/region-space),
- * on either side of mouse click (size of keyframe icon)
- */
-
- /* standard channel height (to allow for some slop) */
- key_hsize = ACHANNEL_HEIGHT(ac) * 0.8f;
- /* half-size (for either side), but rounded up to nearest int (for easier targeting) */
- key_hsize = roundf(key_hsize / 2.0f);
-
- UI_view2d_region_to_view(v2d, mval[0] - (int)key_hsize, mval[1], &rectf.xmin, &rectf.ymin);
- UI_view2d_region_to_view(v2d, mval[0] + (int)key_hsize, mval[1], &rectf.xmax, &rectf.ymax);
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* try to get channel */
- ale = BLI_findlink(&anim_data, channel_index);
- if (ale == NULL) {
- /* channel not found */
- printf("Error: animation channel (index = %d) not found in mouse_action_keys()\n", channel_index);
- ANIM_animdata_freelist(&anim_data);
- return;
- }
- else {
- /* found match - must return here... */
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- ActKeyColumn *ak, *akn = NULL;
-
- /* make list of keyframes */
- BLI_dlrbTree_init(&anim_keys);
-
- if (ale->key_data) {
- switch (ale->datatype) {
- case ALE_SCE:
- {
- Scene *scene = (Scene *)ale->key_data;
- scene_to_keylist(ads, scene, &anim_keys, 0);
- break;
- }
- case ALE_OB:
- {
- Object *ob = (Object *)ale->key_data;
- ob_to_keylist(ads, ob, &anim_keys, 0);
- break;
- }
- case ALE_ACT:
- {
- bAction *act = (bAction *)ale->key_data;
- action_to_keylist(adt, act, &anim_keys, 0);
- break;
- }
- case ALE_FCURVE:
- {
- FCurve *fcu = (FCurve *)ale->key_data;
- fcurve_to_keylist(adt, fcu, &anim_keys, 0);
- break;
- }
- }
- }
- else if (ale->type == ANIMTYPE_SUMMARY) {
- /* dopesheet summary covers everything */
- summary_to_keylist(ac, &anim_keys, 0);
- }
- else if (ale->type == ANIMTYPE_GROUP) {
- // TODO: why don't we just give groups key_data too?
- bActionGroup *agrp = (bActionGroup *)ale->data;
- agroup_to_keylist(adt, agrp, &anim_keys, 0);
- }
- else if (ale->type == ANIMTYPE_GPLAYER) {
- // TODO: why don't we just give gplayers key_data too?
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
- gpl_to_keylist(ads, gpl, &anim_keys);
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- // TODO: why don't we just give masklayers key_data too?
- MaskLayer *masklay = (MaskLayer *)ale->data;
- mask_to_keylist(ads, masklay, &anim_keys);
- }
-
- /* start from keyframe at root of BST,
- * traversing until we find one within the range that was clicked on */
- for (ak = anim_keys.root; ak; ak = akn) {
- if (IN_RANGE(ak->cfra, rectf.xmin, rectf.xmax)) {
- /* set the frame to use, and apply inverse-correction for NLA-mapping
- * so that the frame will get selected by the selection functions without
- * requiring to map each frame once again...
- */
- selx = BKE_nla_tweakedit_remap(adt, ak->cfra, NLATIME_CONVERT_UNMAP);
- frame = ak->cfra;
- found = true;
- break;
- }
- else if (ak->cfra < rectf.xmin)
- akn = ak->right;
- else
- akn = ak->left;
- }
-
- /* remove active channel from list of channels for separate treatment (since it's needed later on) */
- BLI_remlink(&anim_data, ale);
- ale->next = ale->prev = NULL;
-
- /* cleanup temporary lists */
- BLI_dlrbTree_free(&anim_keys);
-
- /* free list of channels, since it's not used anymore */
- ANIM_animdata_freelist(&anim_data);
- }
-
- /* for replacing selection, firstly need to clear existing selection */
- if (select_mode == SELECT_REPLACE) {
- /* reset selection mode for next steps */
- select_mode = SELECT_ADD;
-
- /* deselect all keyframes */
- deselect_action_keys(ac, 0, SELECT_SUBTRACT);
-
- /* highlight channel clicked on */
- if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE)) {
- /* deselect all other channels first */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
-
- /* Highlight Action-Group or F-Curve? */
- if (ale && ale->data) {
- if (ale->type == ANIMTYPE_GROUP) {
- bActionGroup *agrp = ale->data;
-
- agrp->flag |= AGRP_SELECTED;
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
- }
- else if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
- FCurve *fcu = ale->data;
-
- fcu->flag |= FCURVE_SELECTED;
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
- }
- }
- }
- else if (ac->datatype == ANIMCONT_GPENCIL) {
- /* deselect all other channels first */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
-
- /* Highlight GPencil Layer */
- if ((ale && ale->data) && (ale->type == ANIMTYPE_GPLAYER)) {
- bGPDlayer *gpl = ale->data;
-
- gpl->flag |= GP_LAYER_SELECT;
- //gpencil_layer_setactive(gpd, gpl);
- }
- }
- else if (ac->datatype == ANIMCONT_MASK) {
- /* deselect all other channels first */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
-
- /* Highlight GPencil Layer */
- if ((ale && ale->data) && (ale->type == ANIMTYPE_MASKLAYER)) {
- MaskLayer *masklay = ale->data;
-
- masklay->flag |= MASK_LAYERFLAG_SELECT;
- //gpencil_layer_setactive(gpd, gpl);
- }
- }
- }
-
- /* only select keyframes if we clicked on a valid channel and hit something */
- if (ale) {
- if (found) {
- /* apply selection to keyframes */
- if (column) {
- /* select all keyframes in the same frame as the one we hit on the active channel
- * [T41077]: "frame" not "selx" here (i.e. no NLA corrections yet) as the code here
- * does that itself again as it needs to work on multiple datablocks
- */
- actkeys_mselect_column(ac, select_mode, frame);
- }
- else if (same_channel) {
- /* select all keyframes in the active channel */
- actkeys_mselect_channel_only(ac, ale, select_mode);
- }
- else {
- /* select the nominated keyframe on the given frame */
- actkeys_mselect_single(ac, ale, select_mode, selx);
- }
- }
-
- /* flush tagged updates
- * NOTE: We temporarily add this channel back to the list so that this can happen
- */
- anim_data.first = anim_data.last = ale;
- ANIM_animdata_update(ac, &anim_data);
-
- /* free this channel */
- MEM_freeN(ale);
- }
+ ListBase anim_data = {NULL, NULL};
+ DLRBT_Tree anim_keys;
+ bAnimListElem *ale;
+ int filter;
+
+ View2D *v2d = &ac->ar->v2d;
+ bDopeSheet *ads = NULL;
+ int channel_index;
+ bool found = false;
+ float frame = 0.0f; /* frame of keyframe under mouse - NLA corrections not applied/included */
+ float selx = 0.0f; /* frame of keyframe under mouse */
+ float key_hsize;
+ float x, y;
+ rctf rectf;
+
+ /* get dopesheet info */
+ if (ELEM(ac->datatype, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE))
+ ads = ac->data;
+
+ /* use View2D to determine the index of the channel (i.e a row in the list) where keyframe was */
+ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
+ UI_view2d_listview_view_to_cell(
+ v2d, 0, ACHANNEL_STEP(ac), 0, (float)ACHANNEL_HEIGHT_HALF(ac), x, y, NULL, &channel_index);
+
+ /* x-range to check is +/- 7px for standard keyframe under standard dpi/y-scale (in screen/region-space),
+ * on either side of mouse click (size of keyframe icon)
+ */
+
+ /* standard channel height (to allow for some slop) */
+ key_hsize = ACHANNEL_HEIGHT(ac) * 0.8f;
+ /* half-size (for either side), but rounded up to nearest int (for easier targeting) */
+ key_hsize = roundf(key_hsize / 2.0f);
+
+ UI_view2d_region_to_view(v2d, mval[0] - (int)key_hsize, mval[1], &rectf.xmin, &rectf.ymin);
+ UI_view2d_region_to_view(v2d, mval[0] + (int)key_hsize, mval[1], &rectf.xmax, &rectf.ymax);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* try to get channel */
+ ale = BLI_findlink(&anim_data, channel_index);
+ if (ale == NULL) {
+ /* channel not found */
+ printf("Error: animation channel (index = %d) not found in mouse_action_keys()\n",
+ channel_index);
+ ANIM_animdata_freelist(&anim_data);
+ return;
+ }
+ else {
+ /* found match - must return here... */
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ ActKeyColumn *ak, *akn = NULL;
+
+ /* make list of keyframes */
+ BLI_dlrbTree_init(&anim_keys);
+
+ if (ale->key_data) {
+ switch (ale->datatype) {
+ case ALE_SCE: {
+ Scene *scene = (Scene *)ale->key_data;
+ scene_to_keylist(ads, scene, &anim_keys, 0);
+ break;
+ }
+ case ALE_OB: {
+ Object *ob = (Object *)ale->key_data;
+ ob_to_keylist(ads, ob, &anim_keys, 0);
+ break;
+ }
+ case ALE_ACT: {
+ bAction *act = (bAction *)ale->key_data;
+ action_to_keylist(adt, act, &anim_keys, 0);
+ break;
+ }
+ case ALE_FCURVE: {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ fcurve_to_keylist(adt, fcu, &anim_keys, 0);
+ break;
+ }
+ }
+ }
+ else if (ale->type == ANIMTYPE_SUMMARY) {
+ /* dopesheet summary covers everything */
+ summary_to_keylist(ac, &anim_keys, 0);
+ }
+ else if (ale->type == ANIMTYPE_GROUP) {
+ // TODO: why don't we just give groups key_data too?
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+ agroup_to_keylist(adt, agrp, &anim_keys, 0);
+ }
+ else if (ale->type == ANIMTYPE_GPLAYER) {
+ // TODO: why don't we just give gplayers key_data too?
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ gpl_to_keylist(ads, gpl, &anim_keys);
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ // TODO: why don't we just give masklayers key_data too?
+ MaskLayer *masklay = (MaskLayer *)ale->data;
+ mask_to_keylist(ads, masklay, &anim_keys);
+ }
+
+ /* start from keyframe at root of BST,
+ * traversing until we find one within the range that was clicked on */
+ for (ak = anim_keys.root; ak; ak = akn) {
+ if (IN_RANGE(ak->cfra, rectf.xmin, rectf.xmax)) {
+ /* set the frame to use, and apply inverse-correction for NLA-mapping
+ * so that the frame will get selected by the selection functions without
+ * requiring to map each frame once again...
+ */
+ selx = BKE_nla_tweakedit_remap(adt, ak->cfra, NLATIME_CONVERT_UNMAP);
+ frame = ak->cfra;
+ found = true;
+ break;
+ }
+ else if (ak->cfra < rectf.xmin)
+ akn = ak->right;
+ else
+ akn = ak->left;
+ }
+
+ /* remove active channel from list of channels for separate treatment (since it's needed later on) */
+ BLI_remlink(&anim_data, ale);
+ ale->next = ale->prev = NULL;
+
+ /* cleanup temporary lists */
+ BLI_dlrbTree_free(&anim_keys);
+
+ /* free list of channels, since it's not used anymore */
+ ANIM_animdata_freelist(&anim_data);
+ }
+
+ /* for replacing selection, firstly need to clear existing selection */
+ if (select_mode == SELECT_REPLACE) {
+ /* reset selection mode for next steps */
+ select_mode = SELECT_ADD;
+
+ /* deselect all keyframes */
+ deselect_action_keys(ac, 0, SELECT_SUBTRACT);
+
+ /* highlight channel clicked on */
+ if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE)) {
+ /* deselect all other channels first */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+
+ /* Highlight Action-Group or F-Curve? */
+ if (ale && ale->data) {
+ if (ale->type == ANIMTYPE_GROUP) {
+ bActionGroup *agrp = ale->data;
+
+ agrp->flag |= AGRP_SELECTED;
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
+ }
+ else if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
+ FCurve *fcu = ale->data;
+
+ fcu->flag |= FCURVE_SELECTED;
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
+ }
+ }
+ }
+ else if (ac->datatype == ANIMCONT_GPENCIL) {
+ /* deselect all other channels first */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+
+ /* Highlight GPencil Layer */
+ if ((ale && ale->data) && (ale->type == ANIMTYPE_GPLAYER)) {
+ bGPDlayer *gpl = ale->data;
+
+ gpl->flag |= GP_LAYER_SELECT;
+ //gpencil_layer_setactive(gpd, gpl);
+ }
+ }
+ else if (ac->datatype == ANIMCONT_MASK) {
+ /* deselect all other channels first */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+
+ /* Highlight GPencil Layer */
+ if ((ale && ale->data) && (ale->type == ANIMTYPE_MASKLAYER)) {
+ MaskLayer *masklay = ale->data;
+
+ masklay->flag |= MASK_LAYERFLAG_SELECT;
+ //gpencil_layer_setactive(gpd, gpl);
+ }
+ }
+ }
+
+ /* only select keyframes if we clicked on a valid channel and hit something */
+ if (ale) {
+ if (found) {
+ /* apply selection to keyframes */
+ if (column) {
+ /* select all keyframes in the same frame as the one we hit on the active channel
+ * [T41077]: "frame" not "selx" here (i.e. no NLA corrections yet) as the code here
+ * does that itself again as it needs to work on multiple datablocks
+ */
+ actkeys_mselect_column(ac, select_mode, frame);
+ }
+ else if (same_channel) {
+ /* select all keyframes in the active channel */
+ actkeys_mselect_channel_only(ac, ale, select_mode);
+ }
+ else {
+ /* select the nominated keyframe on the given frame */
+ actkeys_mselect_single(ac, ale, select_mode, selx);
+ }
+ }
+
+ /* flush tagged updates
+ * NOTE: We temporarily add this channel back to the list so that this can happen
+ */
+ anim_data.first = anim_data.last = ale;
+ ANIM_animdata_update(ac, &anim_data);
+
+ /* free this channel */
+ MEM_freeN(ale);
+ }
}
/* handle clicking */
static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bAnimContext ac;
- /* ARegion *ar; */ /* UNUSED */
- short selectmode;
- bool column, channel;
+ bAnimContext ac;
+ /* ARegion *ar; */ /* UNUSED */
+ short selectmode;
+ bool column, channel;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get useful pointers from animation context data */
- /* ar = ac.ar; */ /* UNUSED */
+ /* get useful pointers from animation context data */
+ /* ar = ac.ar; */ /* UNUSED */
- /* select mode is either replace (deselect all, then add) or add/extend */
- if (RNA_boolean_get(op->ptr, "extend"))
- selectmode = SELECT_INVERT;
- else
- selectmode = SELECT_REPLACE;
+ /* select mode is either replace (deselect all, then add) or add/extend */
+ if (RNA_boolean_get(op->ptr, "extend"))
+ selectmode = SELECT_INVERT;
+ else
+ selectmode = SELECT_REPLACE;
- /* column selection */
- column = RNA_boolean_get(op->ptr, "column");
- channel = RNA_boolean_get(op->ptr, "channel");
+ /* column selection */
+ column = RNA_boolean_get(op->ptr, "column");
+ channel = RNA_boolean_get(op->ptr, "channel");
- /* select keyframe(s) based upon mouse position*/
- mouse_action_keys(&ac, event->mval, selectmode, column, channel);
+ /* select keyframe(s) based upon mouse position*/
+ mouse_action_keys(&ac, event->mval, selectmode, column, channel);
- /* set notifier that keyframe selection (and channels too) have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection (and channels too) have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
- /* for tweak grab to work */
- return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
+ /* for tweak grab to work */
+ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
void ACTION_OT_clickselect(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Select Keyframes";
- ot->idname = "ACTION_OT_clickselect";
- ot->description = "Select keyframes by clicking on them";
-
- /* callbacks */
- ot->invoke = actkeys_clickselect_invoke;
- ot->poll = ED_operator_action_active;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-
- /* properties */
- prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select",
- "Toggle keyframe selection instead of leaving newly selected keyframes only"); // SHIFTKEY
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select",
- "Select all keyframes that occur on the same frame as the one under the mouse"); // ALTKEY
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "channel", 0, "Only Channel",
- "Select all the keyframes in the channel under the mouse"); // CTRLKEY + ALTKEY
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Select Keyframes";
+ ot->idname = "ACTION_OT_clickselect";
+ ot->description = "Select keyframes by clicking on them";
+
+ /* callbacks */
+ ot->invoke = actkeys_clickselect_invoke;
+ ot->poll = ED_operator_action_active;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_boolean(
+ ot->srna,
+ "extend",
+ 0,
+ "Extend Select",
+ "Toggle keyframe selection instead of leaving newly selected keyframes only"); // SHIFTKEY
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(
+ ot->srna,
+ "column",
+ 0,
+ "Column Select",
+ "Select all keyframes that occur on the same frame as the one under the mouse"); // ALTKEY
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(
+ ot->srna,
+ "channel",
+ 0,
+ "Only Channel",
+ "Select all the keyframes in the channel under the mouse"); // CTRLKEY + ALTKEY
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ************************************************************************** */
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index f2550550bc1..bfbca07d530 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -53,770 +53,784 @@
#include "ED_anim_api.h"
#include "ED_markers.h"
-#include "action_intern.h" /* own include */
+#include "action_intern.h" /* own include */
#include "GPU_framebuffer.h"
/* ******************** manage regions ********************* */
ARegion *action_has_buttons_region(ScrArea *sa)
{
- ARegion *ar, *arnew;
+ ARegion *ar, *arnew;
- ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
- if (ar) return ar;
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
+ if (ar)
+ return ar;
- /* add subdiv level; after main */
- ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ /* add subdiv level; after main */
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- /* is error! */
- if (ar == NULL) return NULL;
+ /* is error! */
+ if (ar == NULL)
+ return NULL;
- arnew = MEM_callocN(sizeof(ARegion), "buttons for action");
+ arnew = MEM_callocN(sizeof(ARegion), "buttons for action");
- BLI_insertlinkafter(&sa->regionbase, ar, arnew);
- arnew->regiontype = RGN_TYPE_UI;
- arnew->alignment = RGN_ALIGN_RIGHT;
+ BLI_insertlinkafter(&sa->regionbase, ar, arnew);
+ arnew->regiontype = RGN_TYPE_UI;
+ arnew->alignment = RGN_ALIGN_RIGHT;
- arnew->flag = RGN_FLAG_HIDDEN;
+ arnew->flag = RGN_FLAG_HIDDEN;
- return arnew;
+ return arnew;
}
/* ******************** default callbacks for action space ***************** */
static SpaceLink *action_new(const ScrArea *sa, const Scene *scene)
{
- SpaceAction *saction;
- ARegion *ar;
+ SpaceAction *saction;
+ ARegion *ar;
- saction = MEM_callocN(sizeof(SpaceAction), "initaction");
- saction->spacetype = SPACE_ACTION;
+ saction = MEM_callocN(sizeof(SpaceAction), "initaction");
+ saction->spacetype = SPACE_ACTION;
- saction->autosnap = SACTSNAP_FRAME;
- saction->mode = SACTCONT_DOPESHEET;
- saction->mode_prev = SACTCONT_DOPESHEET;
- saction->flag = SACTION_SHOW_INTERPOLATION;
+ saction->autosnap = SACTSNAP_FRAME;
+ saction->mode = SACTCONT_DOPESHEET;
+ saction->mode_prev = SACTCONT_DOPESHEET;
+ saction->flag = SACTION_SHOW_INTERPOLATION;
- saction->ads.filterflag |= ADS_FILTER_SUMMARY;
+ saction->ads.filterflag |= ADS_FILTER_SUMMARY;
- /* enable all cache display */
- saction->cache_display |= TIME_CACHE_DISPLAY;
- saction->cache_display |= (TIME_CACHE_SOFTBODY | TIME_CACHE_PARTICLES);
- saction->cache_display |= (TIME_CACHE_CLOTH | TIME_CACHE_SMOKE | TIME_CACHE_DYNAMICPAINT);
- saction->cache_display |= TIME_CACHE_RIGIDBODY;
+ /* enable all cache display */
+ saction->cache_display |= TIME_CACHE_DISPLAY;
+ saction->cache_display |= (TIME_CACHE_SOFTBODY | TIME_CACHE_PARTICLES);
+ saction->cache_display |= (TIME_CACHE_CLOTH | TIME_CACHE_SMOKE | TIME_CACHE_DYNAMICPAINT);
+ saction->cache_display |= TIME_CACHE_RIGIDBODY;
- /* header */
- ar = MEM_callocN(sizeof(ARegion), "header for action");
+ /* header */
+ ar = MEM_callocN(sizeof(ARegion), "header for action");
- BLI_addtail(&saction->regionbase, ar);
- ar->regiontype = RGN_TYPE_HEADER;
- ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
+ BLI_addtail(&saction->regionbase, ar);
+ ar->regiontype = RGN_TYPE_HEADER;
+ ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
- /* channel list region */
- ar = MEM_callocN(sizeof(ARegion), "channel region for action");
- BLI_addtail(&saction->regionbase, ar);
- ar->regiontype = RGN_TYPE_CHANNELS;
- ar->alignment = RGN_ALIGN_LEFT;
+ /* channel list region */
+ ar = MEM_callocN(sizeof(ARegion), "channel region for action");
+ BLI_addtail(&saction->regionbase, ar);
+ ar->regiontype = RGN_TYPE_CHANNELS;
+ ar->alignment = RGN_ALIGN_LEFT;
- /* only need to set scroll settings, as this will use 'listview' v2d configuration */
- ar->v2d.scroll = V2D_SCROLL_BOTTOM;
- ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
+ /* only need to set scroll settings, as this will use 'listview' v2d configuration */
+ ar->v2d.scroll = V2D_SCROLL_BOTTOM;
+ ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
- /* ui buttons */
- ar = MEM_callocN(sizeof(ARegion), "buttons region for action");
+ /* ui buttons */
+ ar = MEM_callocN(sizeof(ARegion), "buttons region for action");
- BLI_addtail(&saction->regionbase, ar);
- ar->regiontype = RGN_TYPE_UI;
- ar->alignment = RGN_ALIGN_RIGHT;
- ar->flag = RGN_FLAG_HIDDEN;
+ BLI_addtail(&saction->regionbase, ar);
+ ar->regiontype = RGN_TYPE_UI;
+ ar->alignment = RGN_ALIGN_RIGHT;
+ ar->flag = RGN_FLAG_HIDDEN;
- /* main region */
- ar = MEM_callocN(sizeof(ARegion), "main region for action");
+ /* main region */
+ ar = MEM_callocN(sizeof(ARegion), "main region for action");
- BLI_addtail(&saction->regionbase, ar);
- ar->regiontype = RGN_TYPE_WINDOW;
+ BLI_addtail(&saction->regionbase, ar);
+ ar->regiontype = RGN_TYPE_WINDOW;
- ar->v2d.tot.xmin = (float)(SFRA - 10);
- ar->v2d.tot.ymin = (float)(-sa->winy) / 3.0f;
- ar->v2d.tot.xmax = (float)(EFRA + 10);
- ar->v2d.tot.ymax = 0.0f;
+ ar->v2d.tot.xmin = (float)(SFRA - 10);
+ ar->v2d.tot.ymin = (float)(-sa->winy) / 3.0f;
+ ar->v2d.tot.xmax = (float)(EFRA + 10);
+ ar->v2d.tot.ymax = 0.0f;
- ar->v2d.cur = ar->v2d.tot;
+ ar->v2d.cur = ar->v2d.tot;
- ar->v2d.min[0] = 0.0f;
- ar->v2d.min[1] = 0.0f;
+ ar->v2d.min[0] = 0.0f;
+ ar->v2d.min[1] = 0.0f;
- ar->v2d.max[0] = MAXFRAMEF;
- ar->v2d.max[1] = FLT_MAX;
+ ar->v2d.max[0] = MAXFRAMEF;
+ ar->v2d.max[1] = FLT_MAX;
- ar->v2d.minzoom = 0.01f;
- ar->v2d.maxzoom = 50;
- ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
- ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
- ar->v2d.keepzoom = V2D_LOCKZOOM_Y;
- ar->v2d.keepofs = V2D_KEEPOFS_Y;
- ar->v2d.align = V2D_ALIGN_NO_POS_Y;
- ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
+ ar->v2d.minzoom = 0.01f;
+ ar->v2d.maxzoom = 50;
+ ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
+ ar->v2d.keepzoom = V2D_LOCKZOOM_Y;
+ ar->v2d.keepofs = V2D_KEEPOFS_Y;
+ ar->v2d.align = V2D_ALIGN_NO_POS_Y;
+ ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
- return (SpaceLink *)saction;
+ return (SpaceLink *)saction;
}
/* not spacelink itself */
static void action_free(SpaceLink *UNUSED(sl))
{
-// SpaceAction *saction = (SpaceAction *) sl;
+ // SpaceAction *saction = (SpaceAction *) sl;
}
-
/* spacetype; init callback */
static void action_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
{
- SpaceAction *saction = sa->spacedata.first;
- saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ SpaceAction *saction = sa->spacedata.first;
+ saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
}
static SpaceLink *action_duplicate(SpaceLink *sl)
{
- SpaceAction *sactionn = MEM_dupallocN(sl);
+ SpaceAction *sactionn = MEM_dupallocN(sl);
- /* clear or remove stuff from old */
+ /* clear or remove stuff from old */
- return (SpaceLink *)sactionn;
+ return (SpaceLink *)sactionn;
}
-
-
/* add handlers, stuff you only do once or on area/region changes */
static void action_main_region_init(wmWindowManager *wm, ARegion *ar)
{
- wmKeyMap *keymap;
+ wmKeyMap *keymap;
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
- /* own keymap */
- keymap = WM_keymap_ensure(wm->defaultconf, "Dopesheet", SPACE_ACTION, 0);
- WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- keymap = WM_keymap_ensure(wm->defaultconf, "Dopesheet Generic", SPACE_ACTION, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ /* own keymap */
+ keymap = WM_keymap_ensure(wm->defaultconf, "Dopesheet", SPACE_ACTION, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Dopesheet Generic", SPACE_ACTION, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
}
static void action_main_region_draw(const bContext *C, ARegion *ar)
{
- /* draw entirely, view changes should be handled here */
- SpaceAction *saction = CTX_wm_space_action(C);
- Scene *scene = CTX_data_scene(C);
- Object *obact = CTX_data_active_object(C);
- bAnimContext ac;
- View2D *v2d = &ar->v2d;
- View2DGrid *grid;
- View2DScrollers *scrollers;
- short marker_flag = 0;
- short cfra_flag = 0;
- short unit = 0;
-
- /* clear and setup matrix */
- UI_ThemeClearColor(TH_BACK);
- GPU_clear(GPU_COLOR_BIT);
-
- UI_view2d_view_ortho(v2d);
-
- /* time grid */
- unit = (saction->flag & SACTION_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
- grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy);
- UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
- UI_view2d_grid_free(grid);
-
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
-
- /* start and end frame */
- ANIM_draw_framerange(scene, v2d);
-
- /* data */
- if (ANIM_animdata_get_context(C, &ac)) {
- draw_channel_strips(&ac, saction, ar);
- }
-
- /* current frame */
- if (saction->flag & SACTION_DRAWTIME) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
- ANIM_draw_cfra(C, v2d, cfra_flag);
-
- /* markers */
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
-
- marker_flag = ((ac.markers && (ac.markers != &ac.scene->markers)) ? DRAW_MARKERS_LOCAL : 0) | DRAW_MARKERS_MARGIN;
- if (saction->flag & SACTION_SHOW_MARKER_LINES) marker_flag |= DRAW_MARKERS_LINES;
- ED_markers_draw(C, marker_flag);
-
- /* caches */
- if (saction->mode == SACTCONT_TIMELINE) {
- timeline_draw_cache(saction, obact, scene);
- }
-
- /* preview range */
- UI_view2d_view_ortho(v2d);
- ANIM_draw_previewrange(C, v2d, 0);
-
- /* callback */
- UI_view2d_view_ortho(v2d);
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
-
- /* reset view matrix */
- UI_view2d_view_restore(C);
-
- /* scrollers */
- scrollers = UI_view2d_scrollers_calc(C, v2d, NULL, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
- UI_view2d_scrollers_draw(C, v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
-
- /* draw current frame number-indicator on top of scrollers */
- if ((saction->flag & SACTION_NODRAWCFRANUM) == 0) {
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
- ANIM_draw_cfra_number(C, v2d, cfra_flag);
- }
+ /* draw entirely, view changes should be handled here */
+ SpaceAction *saction = CTX_wm_space_action(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *obact = CTX_data_active_object(C);
+ bAnimContext ac;
+ View2D *v2d = &ar->v2d;
+ View2DGrid *grid;
+ View2DScrollers *scrollers;
+ short marker_flag = 0;
+ short cfra_flag = 0;
+ short unit = 0;
+
+ /* clear and setup matrix */
+ UI_ThemeClearColor(TH_BACK);
+ GPU_clear(GPU_COLOR_BIT);
+
+ UI_view2d_view_ortho(v2d);
+
+ /* time grid */
+ unit = (saction->flag & SACTION_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
+ grid = UI_view2d_grid_calc(CTX_data_scene(C),
+ v2d,
+ unit,
+ V2D_GRID_CLAMP,
+ V2D_ARG_DUMMY,
+ V2D_ARG_DUMMY,
+ ar->winx,
+ ar->winy);
+ UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
+ UI_view2d_grid_free(grid);
+
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
+
+ /* start and end frame */
+ ANIM_draw_framerange(scene, v2d);
+
+ /* data */
+ if (ANIM_animdata_get_context(C, &ac)) {
+ draw_channel_strips(&ac, saction, ar);
+ }
+
+ /* current frame */
+ if (saction->flag & SACTION_DRAWTIME)
+ cfra_flag |= DRAWCFRA_UNIT_SECONDS;
+ ANIM_draw_cfra(C, v2d, cfra_flag);
+
+ /* markers */
+ UI_view2d_view_orthoSpecial(ar, v2d, 1);
+
+ marker_flag = ((ac.markers && (ac.markers != &ac.scene->markers)) ? DRAW_MARKERS_LOCAL : 0) |
+ DRAW_MARKERS_MARGIN;
+ if (saction->flag & SACTION_SHOW_MARKER_LINES)
+ marker_flag |= DRAW_MARKERS_LINES;
+ ED_markers_draw(C, marker_flag);
+
+ /* caches */
+ if (saction->mode == SACTCONT_TIMELINE) {
+ timeline_draw_cache(saction, obact, scene);
+ }
+
+ /* preview range */
+ UI_view2d_view_ortho(v2d);
+ ANIM_draw_previewrange(C, v2d, 0);
+
+ /* callback */
+ UI_view2d_view_ortho(v2d);
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
+
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
+
+ /* scrollers */
+ scrollers = UI_view2d_scrollers_calc(
+ C, v2d, NULL, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
+ UI_view2d_scrollers_draw(C, v2d, scrollers);
+ UI_view2d_scrollers_free(scrollers);
+
+ /* draw current frame number-indicator on top of scrollers */
+ if ((saction->flag & SACTION_NODRAWCFRANUM) == 0) {
+ UI_view2d_view_orthoSpecial(ar, v2d, 1);
+ ANIM_draw_cfra_number(C, v2d, cfra_flag);
+ }
}
/* add handlers, stuff you only do once or on area/region changes */
static void action_channel_region_init(wmWindowManager *wm, ARegion *ar)
{
- wmKeyMap *keymap;
+ wmKeyMap *keymap;
- /* ensure the 2d view sync works - main region has bottom scroller */
- ar->v2d.scroll = V2D_SCROLL_BOTTOM;
+ /* ensure the 2d view sync works - main region has bottom scroller */
+ ar->v2d.scroll = V2D_SCROLL_BOTTOM;
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
- /* own keymap */
- keymap = WM_keymap_ensure(wm->defaultconf, "Animation Channels", 0, 0);
- WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+ /* own keymap */
+ keymap = WM_keymap_ensure(wm->defaultconf, "Animation Channels", 0, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- keymap = WM_keymap_ensure(wm->defaultconf, "Dopesheet Generic", SPACE_ACTION, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Dopesheet Generic", SPACE_ACTION, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
}
static void action_channel_region_draw(const bContext *C, ARegion *ar)
{
- /* draw entirely, view changes should be handled here */
- bAnimContext ac;
- View2D *v2d = &ar->v2d;
+ /* draw entirely, view changes should be handled here */
+ bAnimContext ac;
+ View2D *v2d = &ar->v2d;
- /* clear and setup matrix */
- UI_ThemeClearColor(TH_BACK);
- GPU_clear(GPU_COLOR_BIT);
+ /* clear and setup matrix */
+ UI_ThemeClearColor(TH_BACK);
+ GPU_clear(GPU_COLOR_BIT);
- UI_view2d_view_ortho(v2d);
+ UI_view2d_view_ortho(v2d);
- /* data */
- if (ANIM_animdata_get_context(C, &ac)) {
- draw_channel_names((bContext *)C, &ac, ar);
- }
+ /* data */
+ if (ANIM_animdata_get_context(C, &ac)) {
+ draw_channel_names((bContext *)C, &ac, ar);
+ }
- /* reset view matrix */
- UI_view2d_view_restore(C);
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
- /* no scrollers here */
+ /* no scrollers here */
}
-
/* add handlers, stuff you only do once or on area/region changes */
static void action_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
{
- ED_region_header_init(ar);
+ ED_region_header_init(ar);
}
static void action_header_region_draw(const bContext *C, ARegion *ar)
{
- ED_region_header(C, ar);
+ ED_region_header(C, ar);
}
-static void action_channel_region_listener(
- wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
- wmNotifier *wmn, const Scene *UNUSED(scene))
+static void action_channel_region_listener(wmWindow *UNUSED(win),
+ ScrArea *UNUSED(sa),
+ ARegion *ar,
+ wmNotifier *wmn,
+ const Scene *UNUSED(scene))
{
- /* context changes */
- switch (wmn->category) {
- case NC_ANIMATION:
- ED_region_tag_redraw(ar);
- break;
- case NC_SCENE:
- switch (wmn->data) {
- case ND_OB_ACTIVE:
- case ND_FRAME:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_OBJECT:
- switch (wmn->data) {
- case ND_BONE_ACTIVE:
- case ND_BONE_SELECT:
- case ND_KEYS:
- ED_region_tag_redraw(ar);
- break;
- case ND_MODIFIER:
- if (wmn->action == NA_RENAME)
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_GPENCIL:
- if (ELEM(wmn->action, NA_RENAME, NA_SELECTED))
- ED_region_tag_redraw(ar);
- break;
- case NC_ID:
- if (wmn->action == NA_RENAME)
- ED_region_tag_redraw(ar);
- break;
- default:
- if (wmn->data == ND_KEYS)
- ED_region_tag_redraw(ar);
- break;
- }
+ /* context changes */
+ switch (wmn->category) {
+ case NC_ANIMATION:
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_OB_ACTIVE:
+ case ND_FRAME:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_OBJECT:
+ switch (wmn->data) {
+ case ND_BONE_ACTIVE:
+ case ND_BONE_SELECT:
+ case ND_KEYS:
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_MODIFIER:
+ if (wmn->action == NA_RENAME)
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_GPENCIL:
+ if (ELEM(wmn->action, NA_RENAME, NA_SELECTED))
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_ID:
+ if (wmn->action == NA_RENAME)
+ ED_region_tag_redraw(ar);
+ break;
+ default:
+ if (wmn->data == ND_KEYS)
+ ED_region_tag_redraw(ar);
+ break;
+ }
}
-static void saction_channel_region_message_subscribe(
- const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene),
- struct bScreen *screen, struct ScrArea *sa, struct ARegion *ar,
- struct wmMsgBus *mbus)
+static void saction_channel_region_message_subscribe(const struct bContext *UNUSED(C),
+ struct WorkSpace *UNUSED(workspace),
+ struct Scene *UNUSED(scene),
+ struct bScreen *screen,
+ struct ScrArea *sa,
+ struct ARegion *ar,
+ struct wmMsgBus *mbus)
{
- PointerRNA ptr;
- RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, sa->spacedata.first, &ptr);
-
- wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
- .owner = ar,
- .user_data = ar,
- .notify = ED_region_do_msg_notify_tag_redraw,
- };
-
- /* All dopesheet filter settings, etc. affect the drawing of this editor,
- * also same applies for all animation-related datatypes that may appear here,
- * so just whitelist the entire structs for updates
- */
- {
- wmMsgParams_RNA msg_key_params = {{{0}}};
- StructRNA *type_array[] = {
- &RNA_DopeSheet, /* dopesheet filters */
-
- &RNA_ActionGroup, /* channel groups */
-
- &RNA_FCurve, /* F-Curve */
- &RNA_Keyframe,
- &RNA_FCurveSample,
-
- &RNA_GreasePencil, /* Grease Pencil */
- &RNA_GPencilLayer,
- &RNA_GPencilFrame,
- };
-
- for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
- msg_key_params.ptr.type = type_array[i];
- WM_msg_subscribe_rna_params(
- mbus,
- &msg_key_params,
- &msg_sub_value_region_tag_redraw,
- __func__);
- }
- }
+ PointerRNA ptr;
+ RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, sa->spacedata.first, &ptr);
+
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ };
+
+ /* All dopesheet filter settings, etc. affect the drawing of this editor,
+ * also same applies for all animation-related datatypes that may appear here,
+ * so just whitelist the entire structs for updates
+ */
+ {
+ wmMsgParams_RNA msg_key_params = {{{0}}};
+ StructRNA *type_array[] = {
+ &RNA_DopeSheet, /* dopesheet filters */
+
+ &RNA_ActionGroup, /* channel groups */
+
+ &RNA_FCurve, /* F-Curve */
+ &RNA_Keyframe,
+ &RNA_FCurveSample,
+
+ &RNA_GreasePencil, /* Grease Pencil */
+ &RNA_GPencilLayer,
+ &RNA_GPencilFrame,
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
+ msg_key_params.ptr.type = type_array[i];
+ WM_msg_subscribe_rna_params(
+ mbus, &msg_key_params, &msg_sub_value_region_tag_redraw, __func__);
+ }
+ }
}
-static void action_main_region_listener(
- wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
- wmNotifier *wmn, const Scene *UNUSED(scene))
+static void action_main_region_listener(wmWindow *UNUSED(win),
+ ScrArea *UNUSED(sa),
+ ARegion *ar,
+ wmNotifier *wmn,
+ const Scene *UNUSED(scene))
{
- /* context changes */
- switch (wmn->category) {
- case NC_ANIMATION:
- ED_region_tag_redraw(ar);
- break;
- case NC_SCENE:
- switch (wmn->data) {
- case ND_RENDER_OPTIONS:
- case ND_OB_ACTIVE:
- case ND_FRAME:
- case ND_FRAME_RANGE:
- case ND_MARKERS:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_OBJECT:
- switch (wmn->data) {
- case ND_TRANSFORM:
- /* moving object shouldn't need to redraw action */
- break;
- case ND_BONE_ACTIVE:
- case ND_BONE_SELECT:
- case ND_KEYS:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_NODE:
- switch (wmn->action) {
- case NA_EDITED:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_ID:
- if (wmn->action == NA_RENAME)
- ED_region_tag_redraw(ar);
- break;
- case NC_SCREEN:
- if (ELEM(wmn->data, ND_LAYER)) {
- ED_region_tag_redraw(ar);
- }
- break;
- default:
- if (wmn->data == ND_KEYS)
- ED_region_tag_redraw(ar);
- break;
- }
+ /* context changes */
+ switch (wmn->category) {
+ case NC_ANIMATION:
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_RENDER_OPTIONS:
+ case ND_OB_ACTIVE:
+ case ND_FRAME:
+ case ND_FRAME_RANGE:
+ case ND_MARKERS:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_OBJECT:
+ switch (wmn->data) {
+ case ND_TRANSFORM:
+ /* moving object shouldn't need to redraw action */
+ break;
+ case ND_BONE_ACTIVE:
+ case ND_BONE_SELECT:
+ case ND_KEYS:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_NODE:
+ switch (wmn->action) {
+ case NA_EDITED:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_ID:
+ if (wmn->action == NA_RENAME)
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_SCREEN:
+ if (ELEM(wmn->data, ND_LAYER)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ default:
+ if (wmn->data == ND_KEYS)
+ ED_region_tag_redraw(ar);
+ break;
+ }
}
-static void saction_main_region_message_subscribe(
- const struct bContext *C,
- struct WorkSpace *workspace, struct Scene *scene,
- struct bScreen *screen, struct ScrArea *sa, struct ARegion *ar,
- struct wmMsgBus *mbus)
+static void saction_main_region_message_subscribe(const struct bContext *C,
+ struct WorkSpace *workspace,
+ struct Scene *scene,
+ struct bScreen *screen,
+ struct ScrArea *sa,
+ struct ARegion *ar,
+ struct wmMsgBus *mbus)
{
- PointerRNA ptr;
- RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, sa->spacedata.first, &ptr);
-
- wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
- .owner = ar,
- .user_data = ar,
- .notify = ED_region_do_msg_notify_tag_redraw,
- };
-
- /* Timeline depends on scene properties. */
- {
- bool use_preview = (scene->r.flag & SCER_PRV_RANGE);
- extern PropertyRNA rna_Scene_frame_start;
- extern PropertyRNA rna_Scene_frame_end;
- extern PropertyRNA rna_Scene_frame_preview_start;
- extern PropertyRNA rna_Scene_frame_preview_end;
- extern PropertyRNA rna_Scene_use_preview_range;
- extern PropertyRNA rna_Scene_frame_current;
- const PropertyRNA *props[] = {
- use_preview ? &rna_Scene_frame_preview_start : &rna_Scene_frame_start,
- use_preview ? &rna_Scene_frame_preview_end : &rna_Scene_frame_end,
- &rna_Scene_use_preview_range,
- &rna_Scene_frame_current,
- };
-
- PointerRNA idptr;
- RNA_id_pointer_create(&scene->id, &idptr);
-
- for (int i = 0; i < ARRAY_SIZE(props); i++) {
- WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_region_tag_redraw, __func__);
- }
- }
-
- /* Now run the general "channels region" one - since channels and main should be in sync */
- saction_channel_region_message_subscribe(C, workspace, scene, screen, sa, ar, mbus);
+ PointerRNA ptr;
+ RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, sa->spacedata.first, &ptr);
+
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ };
+
+ /* Timeline depends on scene properties. */
+ {
+ bool use_preview = (scene->r.flag & SCER_PRV_RANGE);
+ extern PropertyRNA rna_Scene_frame_start;
+ extern PropertyRNA rna_Scene_frame_end;
+ extern PropertyRNA rna_Scene_frame_preview_start;
+ extern PropertyRNA rna_Scene_frame_preview_end;
+ extern PropertyRNA rna_Scene_use_preview_range;
+ extern PropertyRNA rna_Scene_frame_current;
+ const PropertyRNA *props[] = {
+ use_preview ? &rna_Scene_frame_preview_start : &rna_Scene_frame_start,
+ use_preview ? &rna_Scene_frame_preview_end : &rna_Scene_frame_end,
+ &rna_Scene_use_preview_range,
+ &rna_Scene_frame_current,
+ };
+
+ PointerRNA idptr;
+ RNA_id_pointer_create(&scene->id, &idptr);
+
+ for (int i = 0; i < ARRAY_SIZE(props); i++) {
+ WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_region_tag_redraw, __func__);
+ }
+ }
+
+ /* Now run the general "channels region" one - since channels and main should be in sync */
+ saction_channel_region_message_subscribe(C, workspace, scene, screen, sa, ar, mbus);
}
/* editor level listener */
-static void action_listener(
- wmWindow *UNUSED(win), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene))
+static void action_listener(wmWindow *UNUSED(win),
+ ScrArea *sa,
+ wmNotifier *wmn,
+ Scene *UNUSED(scene))
{
- SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
-
- /* context changes */
- switch (wmn->category) {
- case NC_GPENCIL:
- /* only handle these events in GPencil mode for performance considerations */
- if (saction->mode == SACTCONT_GPENCIL) {
- if (wmn->action == NA_EDITED) {
- ED_area_tag_redraw(sa);
- }
- else if (wmn->action == NA_SELECTED) {
- saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
- ED_area_tag_refresh(sa);
- }
- }
- break;
- case NC_ANIMATION:
- /* for NLA tweakmode enter/exit, need complete refresh */
- if (wmn->data == ND_NLA_ACTCHANGE) {
- saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
- ED_area_tag_refresh(sa);
- }
- /* autocolor only really needs to change when channels are added/removed,
- * or previously hidden stuff appears
- * (assume for now that if just adding these works, that will be fine)
- */
- else if (((wmn->data == ND_KEYFRAME) && ELEM(wmn->action, NA_ADDED, NA_REMOVED)) ||
- ((wmn->data == ND_ANIMCHAN) && (wmn->action != NA_SELECTED)))
- {
- ED_area_tag_refresh(sa);
- }
- /* for simple edits to the curve data though (or just plain selections),
- * a simple redraw should work
- * (see T39851 for an example of how this can go wrong)
- */
- else {
- ED_area_tag_redraw(sa);
- }
- break;
- case NC_SCENE:
- switch (wmn->data) {
- case ND_OB_ACTIVE:
- case ND_OB_SELECT:
- /* Selection changed, so force refresh to flush
- * (needs flag set to do syncing). */
- saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
- ED_area_tag_refresh(sa);
- break;
- case ND_RENDER_RESULT:
- ED_area_tag_redraw(sa);
- break;
- case ND_FRAME_RANGE:
- for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- Scene *scene = wmn->reference;
- ar->v2d.tot.xmin = (float)(SFRA - 4);
- ar->v2d.tot.xmax = (float)(EFRA + 4);
- break;
- }
- }
- break;
- default:
- if (saction->mode != SACTCONT_TIMELINE) {
- /* Just redrawing the view will do. */
- ED_area_tag_redraw(sa);
- }
- break;
- }
- break;
- case NC_OBJECT:
- switch (wmn->data) {
- case ND_BONE_SELECT: /* selection changed, so force refresh to flush
- * (needs flag set to do syncing) */
- case ND_BONE_ACTIVE:
- saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
- ED_area_tag_refresh(sa);
- break;
- case ND_TRANSFORM:
- /* moving object shouldn't need to redraw action */
- break;
- case ND_POINTCACHE:
- case ND_MODIFIER:
- case ND_PARTICLE:
- /* only needed in timeline mode */
- if (saction->mode == SACTCONT_TIMELINE) {
- ED_area_tag_refresh(sa);
- ED_area_tag_redraw(sa);
- }
- break;
- default: /* just redrawing the view will do */
- ED_area_tag_redraw(sa);
- break;
- }
- break;
- case NC_MASK:
- if (saction->mode == SACTCONT_MASK) {
- switch (wmn->data) {
- case ND_DATA:
- ED_area_tag_refresh(sa);
- ED_area_tag_redraw(sa);
- break;
- default: /* just redrawing the view will do */
- ED_area_tag_redraw(sa);
- break;
- }
- }
- break;
- case NC_NODE:
- if (wmn->action == NA_SELECTED) {
- /* selection changed, so force refresh to flush (needs flag set to do syncing) */
- saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
- ED_area_tag_refresh(sa);
- }
- break;
- case NC_SPACE:
- switch (wmn->data) {
- case ND_SPACE_DOPESHEET:
- ED_area_tag_redraw(sa);
- break;
- case ND_SPACE_TIME:
- ED_area_tag_redraw(sa);
- break;
- case ND_SPACE_CHANGED:
- saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
- ED_area_tag_refresh(sa);
- break;
- }
- break;
- case NC_WINDOW:
- if (saction->runtime.flag & SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC) {
- /* force redraw/refresh after undo/redo - [#28962] */
- ED_area_tag_refresh(sa);
- }
- break;
- case NC_WM:
- switch (wmn->data) {
- case ND_FILEREAD:
- ED_area_tag_refresh(sa);
- break;
- }
- break;
- }
+ SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
+
+ /* context changes */
+ switch (wmn->category) {
+ case NC_GPENCIL:
+ /* only handle these events in GPencil mode for performance considerations */
+ if (saction->mode == SACTCONT_GPENCIL) {
+ if (wmn->action == NA_EDITED) {
+ ED_area_tag_redraw(sa);
+ }
+ else if (wmn->action == NA_SELECTED) {
+ saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ ED_area_tag_refresh(sa);
+ }
+ }
+ break;
+ case NC_ANIMATION:
+ /* for NLA tweakmode enter/exit, need complete refresh */
+ if (wmn->data == ND_NLA_ACTCHANGE) {
+ saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ ED_area_tag_refresh(sa);
+ }
+ /* autocolor only really needs to change when channels are added/removed,
+ * or previously hidden stuff appears
+ * (assume for now that if just adding these works, that will be fine)
+ */
+ else if (((wmn->data == ND_KEYFRAME) && ELEM(wmn->action, NA_ADDED, NA_REMOVED)) ||
+ ((wmn->data == ND_ANIMCHAN) && (wmn->action != NA_SELECTED))) {
+ ED_area_tag_refresh(sa);
+ }
+ /* for simple edits to the curve data though (or just plain selections),
+ * a simple redraw should work
+ * (see T39851 for an example of how this can go wrong)
+ */
+ else {
+ ED_area_tag_redraw(sa);
+ }
+ break;
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_OB_ACTIVE:
+ case ND_OB_SELECT:
+ /* Selection changed, so force refresh to flush
+ * (needs flag set to do syncing). */
+ saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ ED_area_tag_refresh(sa);
+ break;
+ case ND_RENDER_RESULT:
+ ED_area_tag_redraw(sa);
+ break;
+ case ND_FRAME_RANGE:
+ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ Scene *scene = wmn->reference;
+ ar->v2d.tot.xmin = (float)(SFRA - 4);
+ ar->v2d.tot.xmax = (float)(EFRA + 4);
+ break;
+ }
+ }
+ break;
+ default:
+ if (saction->mode != SACTCONT_TIMELINE) {
+ /* Just redrawing the view will do. */
+ ED_area_tag_redraw(sa);
+ }
+ break;
+ }
+ break;
+ case NC_OBJECT:
+ switch (wmn->data) {
+ case ND_BONE_SELECT: /* selection changed, so force refresh to flush
+ * (needs flag set to do syncing) */
+ case ND_BONE_ACTIVE:
+ saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ ED_area_tag_refresh(sa);
+ break;
+ case ND_TRANSFORM:
+ /* moving object shouldn't need to redraw action */
+ break;
+ case ND_POINTCACHE:
+ case ND_MODIFIER:
+ case ND_PARTICLE:
+ /* only needed in timeline mode */
+ if (saction->mode == SACTCONT_TIMELINE) {
+ ED_area_tag_refresh(sa);
+ ED_area_tag_redraw(sa);
+ }
+ break;
+ default: /* just redrawing the view will do */
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ break;
+ case NC_MASK:
+ if (saction->mode == SACTCONT_MASK) {
+ switch (wmn->data) {
+ case ND_DATA:
+ ED_area_tag_refresh(sa);
+ ED_area_tag_redraw(sa);
+ break;
+ default: /* just redrawing the view will do */
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ }
+ break;
+ case NC_NODE:
+ if (wmn->action == NA_SELECTED) {
+ /* selection changed, so force refresh to flush (needs flag set to do syncing) */
+ saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ ED_area_tag_refresh(sa);
+ }
+ break;
+ case NC_SPACE:
+ switch (wmn->data) {
+ case ND_SPACE_DOPESHEET:
+ ED_area_tag_redraw(sa);
+ break;
+ case ND_SPACE_TIME:
+ ED_area_tag_redraw(sa);
+ break;
+ case ND_SPACE_CHANGED:
+ saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ ED_area_tag_refresh(sa);
+ break;
+ }
+ break;
+ case NC_WINDOW:
+ if (saction->runtime.flag & SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC) {
+ /* force redraw/refresh after undo/redo - [#28962] */
+ ED_area_tag_refresh(sa);
+ }
+ break;
+ case NC_WM:
+ switch (wmn->data) {
+ case ND_FILEREAD:
+ ED_area_tag_refresh(sa);
+ break;
+ }
+ break;
+ }
}
static void action_header_region_listener(
- wmWindow *UNUSED(win), ScrArea *sa, ARegion *ar,
- wmNotifier *wmn, const Scene *UNUSED(scene))
+ wmWindow *UNUSED(win), ScrArea *sa, ARegion *ar, wmNotifier *wmn, const Scene *UNUSED(scene))
{
- SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
-
- /* context changes */
- switch (wmn->category) {
- case NC_SCREEN:
- if (saction->mode == SACTCONT_TIMELINE) {
- if (wmn->data == ND_ANIMPLAY)
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_SCENE:
- if (saction->mode == SACTCONT_TIMELINE) {
- switch (wmn->data) {
- case ND_RENDER_RESULT:
- case ND_OB_SELECT:
- case ND_FRAME:
- case ND_FRAME_RANGE:
- case ND_KEYINGSET:
- case ND_RENDER_OPTIONS:
- ED_region_tag_redraw(ar);
- break;
- }
- }
- else {
- switch (wmn->data) {
- case ND_OB_ACTIVE:
- ED_region_tag_redraw(ar);
- break;
- }
- }
- break;
- case NC_ID:
- if (wmn->action == NA_RENAME)
- ED_region_tag_redraw(ar);
- break;
- case NC_ANIMATION:
- switch (wmn->data) {
- case ND_ANIMCHAN: /* set of visible animchannels changed */
- /* NOTE: for now, this should usually just mean that the filters changed
- * It may be better if we had a dedicated flag for that though
- */
- ED_region_tag_redraw(ar);
- break;
-
- case ND_KEYFRAME: /* new keyframed added -> active action may have changed */
- //saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- }
-
+ SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
+
+ /* context changes */
+ switch (wmn->category) {
+ case NC_SCREEN:
+ if (saction->mode == SACTCONT_TIMELINE) {
+ if (wmn->data == ND_ANIMPLAY)
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_SCENE:
+ if (saction->mode == SACTCONT_TIMELINE) {
+ switch (wmn->data) {
+ case ND_RENDER_RESULT:
+ case ND_OB_SELECT:
+ case ND_FRAME:
+ case ND_FRAME_RANGE:
+ case ND_KEYINGSET:
+ case ND_RENDER_OPTIONS:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ }
+ else {
+ switch (wmn->data) {
+ case ND_OB_ACTIVE:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ }
+ break;
+ case NC_ID:
+ if (wmn->action == NA_RENAME)
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_ANIMATION:
+ switch (wmn->data) {
+ case ND_ANIMCHAN: /* set of visible animchannels changed */
+ /* NOTE: for now, this should usually just mean that the filters changed
+ * It may be better if we had a dedicated flag for that though
+ */
+ ED_region_tag_redraw(ar);
+ break;
+
+ case ND_KEYFRAME: /* new keyframed added -> active action may have changed */
+ //saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ }
}
/* add handlers, stuff you only do once or on area/region changes */
static void action_buttons_area_init(wmWindowManager *wm, ARegion *ar)
{
- wmKeyMap *keymap;
+ wmKeyMap *keymap;
- ED_region_panels_init(wm, ar);
+ ED_region_panels_init(wm, ar);
- keymap = WM_keymap_ensure(wm->defaultconf, "Dopesheet Generic", SPACE_ACTION, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Dopesheet Generic", SPACE_ACTION, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
}
static void action_buttons_area_draw(const bContext *C, ARegion *ar)
{
- ED_region_panels(C, ar);
+ ED_region_panels(C, ar);
}
-static void action_region_listener(
- wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
- wmNotifier *wmn, const Scene *UNUSED(scene))
+static void action_region_listener(wmWindow *UNUSED(win),
+ ScrArea *UNUSED(sa),
+ ARegion *ar,
+ wmNotifier *wmn,
+ const Scene *UNUSED(scene))
{
- /* context changes */
- switch (wmn->category) {
- case NC_ANIMATION:
- ED_region_tag_redraw(ar);
- break;
- case NC_SCENE:
- switch (wmn->data) {
- case ND_OB_ACTIVE:
- case ND_FRAME:
- case ND_MARKERS:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_OBJECT:
- switch (wmn->data) {
- case ND_BONE_ACTIVE:
- case ND_BONE_SELECT:
- case ND_KEYS:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- default:
- if (wmn->data == ND_KEYS)
- ED_region_tag_redraw(ar);
- break;
- }
+ /* context changes */
+ switch (wmn->category) {
+ case NC_ANIMATION:
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_OB_ACTIVE:
+ case ND_FRAME:
+ case ND_MARKERS:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_OBJECT:
+ switch (wmn->data) {
+ case ND_BONE_ACTIVE:
+ case ND_BONE_SELECT:
+ case ND_KEYS:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ default:
+ if (wmn->data == ND_KEYS)
+ ED_region_tag_redraw(ar);
+ break;
+ }
}
static void action_refresh(const bContext *C, ScrArea *sa)
{
- SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
-
- /* update the state of the animchannels in response to changes from the data they represent
- * NOTE: the temp flag is used to indicate when this needs to be done, and will be cleared once handled
- */
- if (saction->runtime.flag & SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC) {
- ARegion *ar;
-
- /* Perform syncing of channel state incl. selection
- * Active action setting also occurs here (as part of anim channel filtering in anim_filter.c)
- */
- ANIM_sync_animchannels_to_data(C);
- saction->runtime.flag &= ~SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
-
- /* Tag everything for redraw
- * - Regions (such as header) need to be manually tagged for redraw too
- * or else they don't update [#28962]
- */
- ED_area_tag_redraw(sa);
- for (ar = sa->regionbase.first; ar; ar = ar->next)
- ED_region_tag_redraw(ar);
- }
-
- /* region updates? */
- // XXX re-sizing y-extents of tot should go here?
+ SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
+
+ /* update the state of the animchannels in response to changes from the data they represent
+ * NOTE: the temp flag is used to indicate when this needs to be done, and will be cleared once handled
+ */
+ if (saction->runtime.flag & SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC) {
+ ARegion *ar;
+
+ /* Perform syncing of channel state incl. selection
+ * Active action setting also occurs here (as part of anim channel filtering in anim_filter.c)
+ */
+ ANIM_sync_animchannels_to_data(C);
+ saction->runtime.flag &= ~SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
+
+ /* Tag everything for redraw
+ * - Regions (such as header) need to be manually tagged for redraw too
+ * or else they don't update [#28962]
+ */
+ ED_area_tag_redraw(sa);
+ for (ar = sa->regionbase.first; ar; ar = ar->next)
+ ED_region_tag_redraw(ar);
+ }
+
+ /* region updates? */
+ // XXX re-sizing y-extents of tot should go here?
}
static void action_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
{
- SpaceAction *sact = (SpaceAction *)slink;
-
- if ((ID *)sact->action == old_id) {
- sact->action = (bAction *)new_id;
- }
-
- if ((ID *)sact->ads.filter_grp == old_id) {
- sact->ads.filter_grp = (Collection *)new_id;
- }
- if ((ID *)sact->ads.source == old_id) {
- sact->ads.source = new_id;
- }
-
+ SpaceAction *sact = (SpaceAction *)slink;
+
+ if ((ID *)sact->action == old_id) {
+ sact->action = (bAction *)new_id;
+ }
+
+ if ((ID *)sact->ads.filter_grp == old_id) {
+ sact->ads.filter_grp = (Collection *)new_id;
+ }
+ if ((ID *)sact->ads.source == old_id) {
+ sact->ads.source = new_id;
+ }
}
/**
@@ -826,100 +840,101 @@ static void action_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, I
*/
static int action_space_subtype_get(ScrArea *sa)
{
- SpaceAction *sact = sa->spacedata.first;
- return sact->mode == SACTCONT_TIMELINE ? SACTCONT_TIMELINE : SACTCONT_DOPESHEET;
+ SpaceAction *sact = sa->spacedata.first;
+ return sact->mode == SACTCONT_TIMELINE ? SACTCONT_TIMELINE : SACTCONT_DOPESHEET;
}
static void action_space_subtype_set(ScrArea *sa, int value)
{
- SpaceAction *sact = sa->spacedata.first;
- if (value == SACTCONT_TIMELINE) {
- if (sact->mode != SACTCONT_TIMELINE) {
- sact->mode_prev = sact->mode;
- }
- sact->mode = value;
- }
- else {
- sact->mode = sact->mode_prev;
- }
+ SpaceAction *sact = sa->spacedata.first;
+ if (value == SACTCONT_TIMELINE) {
+ if (sact->mode != SACTCONT_TIMELINE) {
+ sact->mode_prev = sact->mode;
+ }
+ sact->mode = value;
+ }
+ else {
+ sact->mode = sact->mode_prev;
+ }
}
-static void action_space_subtype_item_extend(
- bContext *UNUSED(C), EnumPropertyItem **item, int *totitem)
+static void action_space_subtype_item_extend(bContext *UNUSED(C),
+ EnumPropertyItem **item,
+ int *totitem)
{
- RNA_enum_items_add(item, totitem, rna_enum_space_action_mode_items);
+ RNA_enum_items_add(item, totitem, rna_enum_space_action_mode_items);
}
/* only called once, from space/spacetypes.c */
void ED_spacetype_action(void)
{
- SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype action");
- ARegionType *art;
-
- st->spaceid = SPACE_ACTION;
- strncpy(st->name, "Action", BKE_ST_MAXNAME);
-
- st->new = action_new;
- st->free = action_free;
- st->init = action_init;
- st->duplicate = action_duplicate;
- st->operatortypes = action_operatortypes;
- st->keymap = action_keymap;
- st->listener = action_listener;
- st->refresh = action_refresh;
- st->id_remap = action_id_remap;
- st->space_subtype_item_extend = action_space_subtype_item_extend;
- st->space_subtype_get = action_space_subtype_get;
- st->space_subtype_set = action_space_subtype_set;
-
- /* regions: main window */
- art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
- art->regionid = RGN_TYPE_WINDOW;
- art->init = action_main_region_init;
- art->draw = action_main_region_draw;
- art->listener = action_main_region_listener;
- art->message_subscribe = saction_main_region_message_subscribe;
- art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
-
- BLI_addhead(&st->regiontypes, art);
-
- /* regions: header */
- art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
- art->regionid = RGN_TYPE_HEADER;
- art->prefsizey = HEADERY;
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
-
- art->init = action_header_region_init;
- art->draw = action_header_region_draw;
- art->listener = action_header_region_listener;
-
- BLI_addhead(&st->regiontypes, art);
-
- /* regions: channels */
- art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
- art->regionid = RGN_TYPE_CHANNELS;
- art->prefsizex = 200;
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
-
- art->init = action_channel_region_init;
- art->draw = action_channel_region_draw;
- art->listener = action_channel_region_listener;
- art->message_subscribe = saction_channel_region_message_subscribe;
-
- BLI_addhead(&st->regiontypes, art);
-
- /* regions: UI buttons */
- art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
- art->regionid = RGN_TYPE_UI;
- art->prefsizex = 200;
- art->keymapflag = ED_KEYMAP_UI;
- art->listener = action_region_listener;
- art->init = action_buttons_area_init;
- art->draw = action_buttons_area_draw;
-
- BLI_addhead(&st->regiontypes, art);
-
- action_buttons_register(art);
-
- BKE_spacetype_register(st);
+ SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype action");
+ ARegionType *art;
+
+ st->spaceid = SPACE_ACTION;
+ strncpy(st->name, "Action", BKE_ST_MAXNAME);
+
+ st->new = action_new;
+ st->free = action_free;
+ st->init = action_init;
+ st->duplicate = action_duplicate;
+ st->operatortypes = action_operatortypes;
+ st->keymap = action_keymap;
+ st->listener = action_listener;
+ st->refresh = action_refresh;
+ st->id_remap = action_id_remap;
+ st->space_subtype_item_extend = action_space_subtype_item_extend;
+ st->space_subtype_get = action_space_subtype_get;
+ st->space_subtype_set = action_space_subtype_set;
+
+ /* regions: main window */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
+ art->regionid = RGN_TYPE_WINDOW;
+ art->init = action_main_region_init;
+ art->draw = action_main_region_draw;
+ art->listener = action_main_region_listener;
+ art->message_subscribe = saction_main_region_message_subscribe;
+ art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: header */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
+ art->regionid = RGN_TYPE_HEADER;
+ art->prefsizey = HEADERY;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
+
+ art->init = action_header_region_init;
+ art->draw = action_header_region_draw;
+ art->listener = action_header_region_listener;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: channels */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
+ art->regionid = RGN_TYPE_CHANNELS;
+ art->prefsizex = 200;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
+
+ art->init = action_channel_region_init;
+ art->draw = action_channel_region_draw;
+ art->listener = action_channel_region_listener;
+ art->message_subscribe = saction_channel_region_message_subscribe;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: UI buttons */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
+ art->regionid = RGN_TYPE_UI;
+ art->prefsizex = 200;
+ art->keymapflag = ED_KEYMAP_UI;
+ art->listener = action_region_listener;
+ art->init = action_buttons_area_init;
+ art->draw = action_buttons_area_draw;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ action_buttons_register(art);
+
+ BKE_spacetype_register(st);
}