diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index eddc94fdc5b..ba1703db895 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -212,6 +212,11 @@ void ED_area_tag_redraw(ScrArea *area); void ED_area_tag_redraw_no_rebuild(ScrArea *area); void ED_area_tag_redraw_regiontype(ScrArea *area, int type); void ED_area_tag_refresh(ScrArea *area); +/** + * For regions that change the region size in their #ARegionType.layout() callback: Mark the area + * as having a changed region size, requiring refitting of regions within the area. + */ +void ED_area_tag_region_size_update(ScrArea *area, ARegion *changed_region); /** * Only exported for WM. */ diff --git a/source/blender/editors/interface/interface_region_hud.cc b/source/blender/editors/interface/interface_region_hud.cc index e2a9fa49542..3777f6ea315 100644 --- a/source/blender/editors/interface/interface_region_hud.cc +++ b/source/blender/editors/interface/interface_region_hud.cc @@ -325,12 +325,12 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area) /* Let 'ED_area_update_region_sizes' do the work of placing the region. * Otherwise we could set the 'region->winrct' & 'region->winx/winy' here. */ if (init) { - area->flag |= AREA_FLAG_REGION_SIZE_UPDATE; + ED_area_tag_region_size_update(area, region); } else { if (region->flag & RGN_FLAG_HIDDEN) { /* Also forces recalculating HUD size in hud_region_layout(). */ - area->flag |= AREA_FLAG_REGION_SIZE_UPDATE; + ED_area_tag_region_size_update(area, region); } region->flag &= ~RGN_FLAG_HIDDEN; } diff --git a/source/blender/editors/screen/area.cc b/source/blender/editors/screen/area.cc index 5c25325c512..6b7b9244907 100644 --- a/source/blender/editors/screen/area.cc +++ b/source/blender/editors/screen/area.cc @@ -752,6 +752,37 @@ void ED_area_tag_refresh(ScrArea *area) } } +void ED_area_tag_region_size_update(ScrArea *area, ARegion *changed_region) +{ + if (!area || (area->flag & AREA_FLAG_REGION_SIZE_UPDATE)) { + return; + } + + area->flag |= AREA_FLAG_REGION_SIZE_UPDATE; + + /* Floating regions don't affect other regions, so the following can be skipped. */ + if (changed_region->alignment == RGN_ALIGN_FLOAT) { + return; + } + + /* Tag the following regions for redraw, since the size change of this region may affect the + * available space for them. */ + for (ARegion *following_region = changed_region->next; following_region; + following_region = following_region->next) + { + /* Overlapping and non-overlapping regions don't affect each others space. So layout changes + * of one don't require redrawing the other. */ + if (changed_region->overlap != following_region->overlap) { + continue; + } + /* Floating regions don't affect space of other regions. */ + if (following_region->alignment == RGN_ALIGN_FLOAT) { + continue; + } + ED_region_tag_redraw(following_region); + } +} + /* *************************************************************** */ const char *ED_area_region_search_filter_get(const ScrArea *area, const ARegion *region) @@ -3111,7 +3142,7 @@ void ED_region_panels_layout_ex(const bContext *C, if ((region->sizex != size_dyn[0]) || (region->sizey != size_dyn[1])) { region->sizex = size_dyn[0]; region->sizey = size_dyn[1]; - area->flag |= AREA_FLAG_REGION_SIZE_UPDATE; + ED_area_tag_region_size_update(area, region); } y = fabsf(region->sizey * UI_SCALE_FAC - 1); } @@ -3432,7 +3463,7 @@ void ED_region_header_layout(const bContext *C, ARegion *region) ScrArea *area = CTX_wm_area(C); region->sizex = new_sizex; - area->flag |= AREA_FLAG_REGION_SIZE_UPDATE; + ED_area_tag_region_size_update(area, region); } UI_block_end(C, block);