Fix #127949: able to pan keys out of view if channels are not shown

The issue was that with a96f1208cc the clamping
of the `View2D` happened in the drawing function
of the channel list. That of course won't work if the
channel list isn't drawn.

The fix is to ALSO clamp in the drawing function of
the main area. The reason this has to be in addition, is that
(I think) the channel box is drawn first. So if the clamping doesn't
happen there, the channels and their keys can lose their vertical
alignment.

Pull Request: https://projects.blender.org/blender/blender/pulls/129864
This commit is contained in:
Christoph Lendenfeld
2024-11-05 15:34:22 +01:00
committed by Christoph Lendenfeld
parent e47e720f06
commit 71692abd59
3 changed files with 37 additions and 29 deletions

View File

@@ -466,25 +466,17 @@ static void draw_keyframes(bAnimContext *ac,
ED_channel_list_free(draw_list);
}
void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region)
void draw_channel_strips(bAnimContext *ac,
SpaceAction *saction,
ARegion *region,
ListBase *anim_data)
{
ListBase anim_data = {nullptr, nullptr};
View2D *v2d = &region->v2d;
/* build list of channels to draw */
eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
ANIMFILTER_LIST_CHANNELS);
size_t 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);
/* Draw the manual frame ranges for actions in the background of the dopesheet.
* The action editor has already drawn the range for its action so it's not needed. */
if (ac->datatype == ANIMCONT_DOPESHEET) {
draw_channel_action_ranges(&anim_data, v2d);
draw_channel_action_ranges(anim_data, v2d);
}
/* Draw the background strips. */
@@ -496,7 +488,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region
GPU_blend(GPU_BLEND_ALPHA);
/* first backdrop strips */
draw_backdrops(ac, anim_data, v2d, pos);
draw_backdrops(ac, *anim_data, v2d, pos);
GPU_blend(GPU_BLEND_NONE);
@@ -511,10 +503,10 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region
}
immUnbindProgram();
draw_keyframes(ac, v2d, saction, anim_data);
draw_keyframes(ac, v2d, saction, *anim_data);
/* free temporary channels used for drawing */
ANIM_animdata_freelist(&anim_data);
ANIM_animdata_freelist(anim_data);
}
/** \} */

View File

@@ -37,7 +37,10 @@ void draw_channel_names(bContext *C,
/**
* Draw keyframes in each channel.
*/
void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region);
void draw_channel_strips(bAnimContext *ac,
SpaceAction *saction,
ARegion *region,
ListBase /* bAnimListElem */ *anim_data);
void timeline_draw_cache(const SpaceAction *saction, const Object *ob, const Scene *scene);

View File

@@ -163,6 +163,16 @@ static void action_main_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);
float pad_bottom = add_marker_padding ? UI_MARKER_MARGIN_Y : 0;
/* Add padding for the collapsed redo panel. */
pad_bottom += HEADERY;
v2d->tot.ymin = -(height + pad_bottom);
UI_view2d_curRect_clamp_y(v2d);
}
static void action_main_region_draw(const bContext *C, ARegion *region)
{
/* draw entirely, view changes should be handled here */
@@ -172,6 +182,19 @@ static void action_main_region_draw(const bContext *C, ARegion *region)
View2D *v2d = &region->v2d;
short marker_flag = 0;
ListBase anim_data = {nullptr, nullptr};
const bool has_anim_context = ANIM_animdata_get_context(C, &ac);
if (has_anim_context) {
/* Build list of channels to draw. */
const eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
ANIMFILTER_LIST_CHANNELS);
const size_t items = 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, items, !BLI_listbase_is_empty(ac.markers));
}
UI_view2d_view_ortho(v2d);
/* clear and setup matrix */
@@ -196,8 +219,8 @@ static void action_main_region_draw(const bContext *C, ARegion *region)
}
/* data */
if (ANIM_animdata_get_context(C, &ac)) {
draw_channel_strips(&ac, saction, region);
if (has_anim_context) {
draw_channel_strips(&ac, saction, region, &anim_data);
}
/* markers */
@@ -271,16 +294,6 @@ 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);
float pad_bottom = add_marker_padding ? UI_MARKER_MARGIN_Y : 0;
/* Add padding for the collapsed redo panel. */
pad_bottom += HEADERY;
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 */