diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/animation/anim_channels_defines.c | 108 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_channels_edit.c | 34 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 123 | ||||
-rw-r--r-- | source/blender/editors/include/ED_anim_api.h | 4 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_draw.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_buttons.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_channels.c | 19 |
7 files changed, 287 insertions, 3 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index d48798ece97..23009ae5385 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -626,6 +626,111 @@ static bAnimChannelType ACF_SCENE = acf_scene_setting_ptr /* pointer for setting */ }; +/* Collection ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_collection_icon(bAnimListElem *UNUSED(ale)) +{ + return ICON_GROUP; +} + +/* check if some setting exists for this channel */ +static bool acf_collection_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting) +{ + switch (setting) { + /* muted only in NLA */ + case ACHANNEL_SETTING_MUTE: + return ((ac) && (ac->spacetype == SPACE_NLA)); + + /* visible only in Graph Editor */ + case ACHANNEL_SETTING_VISIBLE: + return ((ac) && (ac->spacetype == SPACE_IPO)); + + /* only select and expand supported otherwise */ + case ACHANNEL_SETTING_SELECT: + case ACHANNEL_SETTING_EXPAND: + return true; + + case ACHANNEL_SETTING_ALWAYS_VISIBLE: + return false; + + default: + return false; + } +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_collection_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg) +{ + /* clear extra return data first */ + *neg = false; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return COLLECTION_DS_SELECTED; + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + *neg = true; + return COLLECTION_DS_COLLAPSED; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ + *neg = true; + return ADT_CURVES_NOT_VISIBLE; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_collection_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type) +{ + Collection *collection = (Collection *)ale->data; + + /* clear extra return data first */ + *type = 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return GET_ACF_FLAG_PTR(collection->flag, type); + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return GET_ACF_FLAG_PTR(collection->flag, type); + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ + if (collection->adt) + return GET_ACF_FLAG_PTR(collection->adt->flag, type); + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* collection type define */ +static bAnimChannelType ACF_COLLECTION = +{ + "Collection", /* type name */ + ACHANNEL_ROLE_EXPANDER, /* role */ + + acf_generic_root_color, /* backdrop color */ + acf_generic_root_backdrop, /* backdrop */ + acf_generic_indention_0, /* indent level */ + NULL, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_generic_idblock_name_prop, /* name prop */ + acf_collection_icon, /* icon */ + + acf_collection_setting_valid, /* has setting */ + acf_collection_setting_flag, /* flag for setting */ + acf_collection_setting_ptr /* pointer for setting */ +}; + /* Object ------------------------------------------- */ static int acf_object_icon(bAnimListElem *ale) @@ -3567,8 +3672,9 @@ static void ANIM_init_channel_typeinfo_data(void) animchannelTypeInfo[type++] = &ACF_SUMMARY; /* Motion Summary */ animchannelTypeInfo[type++] = &ACF_SCENE; /* Scene */ + animchannelTypeInfo[type++] = &ACF_COLLECTION; /* Collection */ animchannelTypeInfo[type++] = &ACF_OBJECT; /* Object */ - animchannelTypeInfo[type++] = &ACF_GROUP; /* Group */ + animchannelTypeInfo[type++] = &ACF_GROUP; /* ActionGroup */ animchannelTypeInfo[type++] = &ACF_FCURVE; /* F-Curve */ animchannelTypeInfo[type++] = &ACF_NLACONTROLS; /* NLA Control FCurve Expander */ diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 6d9a2d3b2b7..5b174d6506e 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -280,6 +280,10 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d if (ale->flag & SCE_DS_SELECTED) sel = ACHANNEL_SETFLAG_CLEAR; break; + case ANIMTYPE_COLLECTION: + if (ale->flag & COLLECTION_DS_SELECTED) + sel = ACHANNEL_SETFLAG_CLEAR; + break; case ANIMTYPE_OBJECT: #if 0 /* for now, do not take object selection into account, since it gets too annoying */ if (ale->flag & SELECT) @@ -354,6 +358,17 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d } break; } + case ANIMTYPE_COLLECTION: + { + Collection *collection = (Collection *)ale->data; + + ACHANNEL_SET_FLAG(collection, sel, COLLECTION_DS_SELECTED); + + if (collection->adt) { + ACHANNEL_SET_FLAG(collection, sel, ADT_UI_SELECTED); + } + break; + } case ANIMTYPE_OBJECT: { #if 0 /* for now, do not take object selection into account, since it gets too annoying */ @@ -2681,6 +2696,25 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index, notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); break; } + case ANIMTYPE_COLLECTION: + { + Collection *collection = (Collection *)ale->data; + AnimData *adt = collection->adt; + + /* set selection status */ + if (selectmode == SELECT_INVERT) { + /* swap select */ + collection->flag ^= COLLECTION_DS_SELECTED; + if (adt) adt->flag ^= ADT_UI_SELECTED; + } + else { + collection->flag |= COLLECTION_DS_SELECTED; + if (adt) adt->flag |= ADT_UI_SELECTED; + } + + notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); + break; + } case ANIMTYPE_OBJECT: { #if 0 diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 0fd97dfb182..1cda7e77dc5 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -614,6 +614,19 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->adt = BKE_animdata_from_id(data); break; } + case ANIMTYPE_COLLECTION: + { + Collection *collection = (Collection *)data; + + ale->flag = collection->flag; + + /* XXX: Nothing to include here for now... to be populated later */ + ale->key_data = NULL; + ale->datatype = ALE_NONE; + + ale->adt = BKE_animdata_from_id(data); + break; + } case ANIMTYPE_OBJECT: { Base *base = (Base *)data; @@ -2630,6 +2643,102 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data return items; } +/* animation channels for collection */ +static size_t animdata_filter_ds_collection(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Collection *collection, int filter_mode) +{ + ListBase tmp_data = {NULL, NULL}; + size_t tmp_items = 0; + size_t items = 0; + + AnimData *adt = collection->adt; + short type = 0, expanded = 1; + void *cdata = NULL; + + /* determine the type of expander channels to use */ + // this is the best way to do this for now... + ANIMDATA_FILTER_CASES(collection, + { /* AnimData - no channel, but consider data */}, + { /* NLA - no channel, but consider data */}, + { /* Drivers */ + type = ANIMTYPE_FILLDRIVERS; + cdata = adt; + expanded = EXPANDED_DRVD(adt); + }, + { /* NLA Strip Controls - no dedicated channel for now (XXX) */ }, + { /* Keyframes */ + type = ANIMTYPE_FILLACTD; + cdata = adt->action; + expanded = EXPANDED_ACTC(adt->action); + }); + + /* add scene-level animation channels */ + BEGIN_ANIMFILTER_SUBCHANNELS(expanded) + { + /* animation data filtering */ + tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)collection, filter_mode); + } + END_ANIMFILTER_SUBCHANNELS; + + /* did we find anything? */ + if (tmp_items) { + /* include anim-expand widget first */ + if (filter_mode & ANIMFILTER_LIST_CHANNELS) { + if (type != ANIMTYPE_NONE) { + /* NOTE: active-status (and the associated checks) don't apply here... */ + ANIMCHANNEL_NEW_CHANNEL(cdata, type, collection); + } + } + + /* now add the list of collected channels */ + BLI_movelisttolist(anim_data, &tmp_data); + BLI_assert(BLI_listbase_is_empty(&tmp_data)); + items += tmp_items; + } + + /* return the number of items added to the list */ + return items; +} + +/* collection animation */ +static size_t animdata_filter_dopesheet_collection(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Collection *collection, int filter_mode) +{ + ListBase tmp_data = {NULL, NULL}; + size_t tmp_items = 0; + size_t items = 0; + + /* filter data contained under collection first */ + BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_COLLECTIONC(collection)) + { + /* Action, Drivers, or NLA for Collection itself */ + //if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) { + tmp_items += animdata_filter_ds_collection(ac, &tmp_data, ads, collection, filter_mode); + //} + + /* TODO: Allow showing for stuff inside collection? */ + } + END_ANIMFILTER_SUBCHANNELS; + + /* if we collected some channels, add these to the new list... */ + if (tmp_items) { + /* firstly add object expander if required */ + if (filter_mode & ANIMFILTER_LIST_CHANNELS) { + /* check if filtering by selection */ + if (ANIMCHANNEL_SELOK((collection->flag & COLLECTION_DS_SELECTED))) { + /* NOTE: active-status doesn't matter for this! */ + ANIMCHANNEL_NEW_CHANNEL(collection, ANIMTYPE_COLLECTION, collection); + } + } + + /* now add the list of collected channels */ + BLI_movelisttolist(anim_data, &tmp_data); + BLI_assert(BLI_listbase_is_empty(&tmp_data)); + items += tmp_items; + } + + /* return the number of items added */ + return items; +} + static size_t animdata_filter_ds_world(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, World *wo, int filter_mode) { ListBase tmp_data = {NULL, NULL}; @@ -2729,7 +2838,7 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d size_t tmp_items = 0; size_t items = 0; - /* filter data contained under object first */ + /* filter data contained under scene first */ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_SCEC(sce)) { bNodeTree *ntree = sce->nodetree; @@ -2969,7 +3078,13 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b /* scene-linked animation - e.g. world, compositing nodes, scene anim (including sequencer currently) */ items += animdata_filter_dopesheet_scene(ac, anim_data, ads, scene, filter_mode); - + + /* collection animation */ + /* XXX: Just list all collections for now */ + for (Collection *collection = G.main->collection.first; collection; collection = collection->id.next) { + items += animdata_filter_dopesheet_collection(ac, anim_data, ads, collection, filter_mode); + } + /* If filtering for channel drawing, we want the objects in alphabetical order, * to make it easier to predict where items are in the hierarchy * - This order only really matters if we need to show all channels in the list (e.g. for drawing) @@ -3074,6 +3189,10 @@ static size_t animdata_filter_animchan(bAnimContext *ac, ListBase *anim_data, bD case ANIMTYPE_SCENE: items += animdata_filter_dopesheet_scene(ac, anim_data, ads, channel->data, filter_mode); break; + + case ANIMTYPE_COLLECTION: + items += animdata_filter_dopesheet_collection(ac, anim_data, ads, channel->data, filter_mode); + break; case ANIMTYPE_OBJECT: items += animdata_filter_dopesheet_ob(ac, anim_data, ads, channel->data, filter_mode); diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index a25b1b84cc5..7474b4a72bd 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -155,6 +155,7 @@ typedef enum eAnim_ChannelType { ANIMTYPE_SUMMARY, ANIMTYPE_SCENE, + ANIMTYPE_COLLECTION, ANIMTYPE_OBJECT, ANIMTYPE_GROUP, ANIMTYPE_FCURVE, @@ -281,6 +282,9 @@ typedef enum eAnimFilter_Flags { /* 'Sub-Scene' channels (flags stored in Data block) */ #define FILTER_WOR_SCED(wo) (CHECK_TYPE_INLINE(wo, World *), (wo->flag & WO_DS_EXPAND)) #define FILTER_LS_SCED(linestyle) ((linestyle->flag & LS_DS_EXPAND)) +/* 'Collection' channels */ +#define SEL_COLLECTIONC(collection) (CHECK_TYPE_INLINE(collection, Collection *), ((collection->flag & COLLECTION_DS_SELECTED))) +#define EXPANDED_COLLECTIONC(collection) (CHECK_TYPE_INLINE(collection, Collection *), ((collection->flag & COLLECTION_DS_COLLAPSED) == 0)) /* 'Object' channels */ #define SEL_OBJC(base) (CHECK_TYPE_INLINE(base, Base *), ((base->flag & SELECT))) #define EXPANDED_OBJC(ob) (CHECK_TYPE_INLINE(ob, Object *), ((ob->nlaflag & OB_ADS_COLLAPSED) == 0)) diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 3e9b742480a..8ce2288dbd3 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -243,6 +243,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) break; } case ANIMTYPE_SCENE: + case ANIMTYPE_COLLECTION: case ANIMTYPE_OBJECT: { immUniformColor3ubvAlpha(col1b, sel ? 0x45 : 0x22); diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index c173aac1a26..3c61fb6fbcf 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -127,6 +127,7 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p break; } case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */ + case ANIMTYPE_COLLECTION: case ANIMTYPE_OBJECT: case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ case ANIMTYPE_DSLAM: diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index 9b7a49ec624..b8588842ece 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -122,6 +122,25 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); break; } + case ANIMTYPE_COLLECTION: + { + Collection *collection = (Collection *)ale->data; + AnimData *adt = collection->adt; + + /* set selection status */ + if (selectmode == SELECT_INVERT) { + /* swap select */ + collection->flag ^= COLLECTION_DS_SELECTED; + if (adt) adt->flag ^= ADT_UI_SELECTED; + } + else { + collection->flag |= COLLECTION_DS_SELECTED; + if (adt) adt->flag |= ADT_UI_SELECTED; + } + + notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); + break; + } case ANIMTYPE_OBJECT: { ViewLayer *view_layer = ac->view_layer; |