Fix #97202: Channels of animation editors disappearing when applying filters #118006

Merged
Christoph Lendenfeld merged 5 commits from ChrisLend/blender:fix_channels_filter_to_empty into blender-v4.1-release 2024-02-29 10:33:13 +01:00
9 changed files with 91 additions and 94 deletions

View File

@ -55,23 +55,13 @@
/** \name Channel List
* \{ */
void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
void draw_channel_names(bContext *C,

Can have a comment here too:

const ListBase /*bAnimListElem*/ &anim_data

Can have a comment here too: `const ListBase /*bAnimListElem*/ &anim_data`
bAnimContext *ac,
ARegion *region,
const ListBase /* bAnimListElem */ &anim_data)
{
ListBase anim_data = {nullptr, nullptr};
bAnimListElem *ale;
eAnimFilter_Flags filter;
View2D *v2d = &region->v2d;
size_t items;
/* 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, eAnimCont_Types(ac->datatype));
const int height = ANIM_UI_get_channels_total_height(v2d, items);
const float pad_bottom = BLI_listbase_is_empty(ac->markers) ? 0 : UI_MARKER_MARGIN_Y;
v2d->tot.ymin = -(height + pad_bottom);
/* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */
UI_view2d_sync(nullptr, ac->area, v2d, V2D_LOCK_COPY);
@ -119,9 +109,6 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
UI_block_end(C, block);
UI_block_draw(C, block);
}
/* Free temporary channels. */
ANIM_animdata_freelist(&anim_data);
}
/** \} */

View File

@ -30,7 +30,10 @@ void action_buttons_register(ARegionType *art);
/**
* Left hand part.
*/
void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region);
void draw_channel_names(bContext *C,
bAnimContext *ac,
ARegion *region,
const ListBase /* bAnimListElem */ &anim_data);
/**
* Draw keyframes in each channel.
*/

View File

@ -271,21 +271,39 @@ static void action_channel_region_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler(&region->handlers, keymap);
}
static void set_v2d_height(View2D *v2d, const size_t item_count, const bool add_marker_padding)
{
const int height = ANIM_UI_get_channels_total_height(v2d, item_count);
const float pad_bottom = add_marker_padding ? UI_MARKER_MARGIN_Y : 0;
v2d->tot.ymin = -(height + pad_bottom);
UI_view2d_curRect_clamp_y(v2d);
}
static void action_channel_region_draw(const bContext *C, ARegion *region)
{
/* draw entirely, view changes should be handled here */
bAnimContext ac;
if (!ANIM_animdata_get_context(C, &ac)) {
return;
}
View2D *v2d = &region->v2d;
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
UI_view2d_view_ortho(v2d);
ListBase anim_data = {nullptr, nullptr};
/* Build list of channels to draw. */
const eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
ANIMFILTER_LIST_CHANNELS);
const size_t item_count = ANIM_animdata_filter(
&ac, &anim_data, filter, ac.data, eAnimCont_Types(ac.datatype));
/* The View2D's height needs to be set before calling UI_view2d_view_ortho because the latter
* uses the View2D's `cur` rect which might be modified when setting the height. */
set_v2d_height(v2d, item_count, !BLI_listbase_is_empty(ac.markers));
/* data */
if (ANIM_animdata_get_context(C, &ac)) {
draw_channel_names((bContext *)C, &ac, region);
}
UI_view2d_view_ortho(v2d);
draw_channel_names((bContext *)C, &ac, region, anim_data);
/* channel filter next to scrubbing area */
ED_time_scrub_channel_search_draw(C, region, ac.ads);
@ -294,6 +312,7 @@ static void action_channel_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
/* no scrollers here */
ANIM_animdata_freelist(&anim_data);
}
/* add handlers, stuff you only do once or on area/region changes */
@ -857,12 +876,6 @@ static void action_space_blend_write(BlendWriter *writer, SpaceLink *sl)
BLO_write_struct(writer, SpaceAction, sl);
}
static void action_main_region_view2d_changed(const bContext * /*C*/, ARegion *region)
{
View2D *v2d = &region->v2d;
UI_view2d_curRect_clamp_y(v2d);
}
void ED_spacetype_action()
{
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
@ -896,7 +909,6 @@ void ED_spacetype_action()
art->draw_overlay = action_main_region_draw_overlay;
art->listener = action_main_region_listener;
art->message_subscribe = saction_main_region_message_subscribe;
art->on_view2d_changed = action_main_region_view2d_changed;
art->keymapflag = ED_KEYMAP_GIZMO | ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);

View File

@ -1521,27 +1521,15 @@ void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, shor
/** \name Channel List
* \{ */
void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
void graph_draw_channel_names(bContext *C,
bAnimContext *ac,
ARegion *region,
const ListBase /* bAnimListElem */ &anim_data)

Same, add comment to ListBase

Same, add comment to `ListBase`
{
ListBase anim_data = {nullptr, nullptr};
bAnimListElem *ale;
int filter;
View2D *v2d = &region->v2d;
float height;
size_t items;
/* build list of channels to draw */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS |
ANIMFILTER_FCURVESONLY);
items = ANIM_animdata_filter(
ac, &anim_data, eAnimFilter_Flags(filter), ac->data, eAnimCont_Types(ac->datatype));
/* Update max-extent of channels here (taking into account scrollers):
* - this is done to allow the channel list to be scrollable, but must be done here
* to avoid regenerating the list again and/or also because channels list is drawn first */
height = ANIM_UI_get_channels_total_height(v2d, items);
v2d->tot.ymin = -height;
const float channel_step = ANIM_UI_get_channel_step();
/* Loop through channels, and set up drawing depending on their type. */

Is this comment still relevant? I might be mis-reading it, but I think it was referring to the code that got removed.

Is this comment still relevant? I might be mis-reading it, but I think it was referring to the code that got removed.
@ -1592,9 +1580,6 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
GPU_blend(GPU_BLEND_NONE);
}
/* Free temporary channels. */
ANIM_animdata_freelist(&anim_data);
}
/** \} */

View File

@ -27,7 +27,10 @@ extern "C" {
/**
* Left hand part.
*/
void graph_draw_channel_names(struct bContext *C, struct bAnimContext *ac, struct ARegion *region);
void graph_draw_channel_names(struct bContext *C,
struct bAnimContext *ac,
struct ARegion *region,
const ListBase /* bAnimListElem */ &anim_data);

Would these be bAnimListElem?

Also, why is this a pointer, while the other two are references?

Would these be `bAnimListElem`? Also, why is this a pointer, while the other two are references?

🤦 yes you are right
not sure why I made this one a pointer, changed it to a const reference

🤦 yes you are right not sure why I made this one a pointer, changed it to a const reference
/**
* This is called twice from `space_graph.cc`, #graph_main_region_draw()

View File

@ -368,20 +368,34 @@ static void graph_channel_region_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler(&region->handlers, keymap);
}
static void set_v2d_height(View2D *v2d, const size_t item_count)
{
const int height = ANIM_UI_get_channels_total_height(v2d, item_count);
v2d->tot.ymin = -height;
UI_view2d_curRect_clamp_y(v2d);
}
static void graph_channel_region_draw(const bContext *C, ARegion *region)
{
bAnimContext ac;
if (!ANIM_animdata_get_context(C, &ac)) {
return;
}
View2D *v2d = &region->v2d;
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
ListBase anim_data = {nullptr, nullptr};
const eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
ANIMFILTER_LIST_CHANNELS | ANIMFILTER_FCURVESONLY);
const size_t item_count = ANIM_animdata_filter(
&ac, &anim_data, filter, ac.data, eAnimCont_Types(ac.datatype));
set_v2d_height(v2d, item_count);
UI_view2d_view_ortho(v2d);
/* draw channels */
if (ANIM_animdata_get_context(C, &ac)) {
graph_draw_channel_names((bContext *)C, &ac, region);
}
graph_draw_channel_names((bContext *)C, &ac, region, anim_data);
/* channel filter next to scrubbing area */
ED_time_scrub_channel_search_draw(C, region, ac.ads);
@ -391,6 +405,8 @@ static void graph_channel_region_draw(const bContext *C, ARegion *region)
/* scrollers */
UI_view2d_scrollers_draw(v2d, nullptr);
ANIM_animdata_freelist(&anim_data);
}
/* add handlers, stuff you only do once or on area/region changes */

View File

@ -913,27 +913,14 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region)
/* *********************************************** */
/* Track List */
void draw_nla_track_list(const bContext *C, bAnimContext *ac, ARegion *region)
void draw_nla_track_list(const bContext *C,
bAnimContext *ac,
ARegion *region,
const ListBase /* bAnimListElem */ &anim_data)
{
ListBase anim_data = {nullptr, nullptr};
SpaceNla *snla = reinterpret_cast<SpaceNla *>(ac->sl);
View2D *v2d = &region->v2d;
size_t items;
/* build list of tracks to draw */
eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
ANIMFILTER_LIST_CHANNELS | ANIMFILTER_FCURVESONLY);
items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
/* Update max-extent of tracks here (taking into account scrollers):
* - this is done to allow the track list to be scrollable, but must be done here
* to avoid regenerating the list again and/or also because tracks list is drawn first
* - offset of NLATRACK_HEIGHT*2 is added to the height of the tracks, as first is for
* start of list offset, and the second is as a correction for the scrollers.
*/
int height = NLATRACK_TOT_HEIGHT(ac, items);
v2d->tot.ymin = -height;
/* need to do a view-sync here, so that the keys area doesn't jump around
* (it must copy this) */
@ -988,9 +975,6 @@ void draw_nla_track_list(const bContext *C, bAnimContext *ac, ARegion *region)
GPU_blend(GPU_BLEND_NONE);
}
/* free temporary tracks */
ANIM_animdata_freelist(&anim_data);
}
/* *********************************************** */

View File

@ -27,7 +27,10 @@ void nla_buttons_register(ARegionType *art);
/* `nla_draw.cc` */
void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region);
void draw_nla_track_list(const bContext *C, bAnimContext *ac, ARegion *region);
void draw_nla_track_list(const bContext *C,
bAnimContext *ac,
ARegion *region,
const ListBase /* bAnimListElem */ &anim_data);

Same here: would these be bAnimListElem?

Same here: would these be `bAnimListElem`?
/* **************************************** */
/* `nla_select.cc` */

View File

@ -176,17 +176,35 @@ static void nla_track_region_init(wmWindowManager *wm, ARegion *region)
static void nla_track_region_draw(const bContext *C, ARegion *region)
{
bAnimContext ac;
View2D *v2d = &region->v2d;
if (!ANIM_animdata_get_context(C, &ac)) {
return;
}
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
ListBase anim_data = {nullptr, nullptr};
SpaceNla *snla = reinterpret_cast<SpaceNla *>(ac.sl);
View2D *v2d = &region->v2d;
const eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
ANIMFILTER_LIST_CHANNELS | ANIMFILTER_FCURVESONLY);
const size_t item_count = ANIM_animdata_filter(
&ac, &anim_data, filter, ac.data, eAnimCont_Types(ac.datatype));
/* Recalculate the height of the track list. Needs to be done before the call to
* `UI_view2d_view_ortho`.*/
int height = NLATRACK_TOT_HEIGHT(&ac, item_count);
if (!BLI_listbase_is_empty(ED_context_get_markers(C))) {
height -= (UI_MARKER_MARGIN_Y - NLATRACK_STEP(snla));
}
v2d->tot.ymin = -height;
UI_view2d_curRect_clamp_y(v2d);
UI_view2d_view_ortho(v2d);
/* data */
if (ANIM_animdata_get_context(C, &ac)) {
draw_nla_track_list(C, &ac, region);
}
draw_nla_track_list(C, &ac, region, anim_data);
/* track filter next to scrubbing area */
ED_time_scrub_channel_search_draw(C, region, ac.ads);
@ -196,6 +214,7 @@ static void nla_track_region_draw(const bContext *C, ARegion *region)
/* scrollers */
UI_view2d_scrollers_draw(v2d, nullptr);
ANIM_animdata_freelist(&anim_data);
}
/* add handlers, stuff you only do once or on area/region changes */
@ -430,20 +449,6 @@ static void nla_main_region_message_subscribe(const wmRegionMessageSubscribePara
}
}
static void nla_main_region_view2d_changed(const bContext *C, ARegion *region)
{
SpaceNla *snla = CTX_wm_space_nla(C);
View2D *v2d = &region->v2d;
/* If markers are present add region padding
* so bottom strip isn't hidden.
*/
if (!BLI_listbase_is_empty(ED_context_get_markers(C))) {
v2d->tot.ymin -= (UI_MARKER_MARGIN_Y - NLATRACK_STEP(snla));
}
UI_view2d_curRect_clamp_y(v2d);
}
static void nla_track_region_listener(const wmRegionListenerParams *params)
{
ARegion *region = params->region;
@ -625,7 +630,6 @@ void ED_spacetype_nla()
art->draw_overlay = nla_main_region_draw_overlay;
art->listener = nla_main_region_listener;
art->message_subscribe = nla_main_region_message_subscribe;
art->on_view2d_changed = nla_main_region_view2d_changed;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);