diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 948299ae29a..6ce89b3448d 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -155,6 +155,14 @@ typedef struct wmRegionMessageSubscribeParams { struct ARegion *region; } wmRegionMessageSubscribeParams; +typedef struct RegionPollParams { + const struct bScreen *screen; + const struct ScrArea *area; + const struct ARegion *region; + + /* For now only WM context members here, could add the scene or even #bContext if needed. */ +} RegionPollParams; + typedef struct ARegionType { struct ARegionType *next, *prev; @@ -164,6 +172,13 @@ typedef struct ARegionType { void (*init)(struct wmWindowManager *wm, struct ARegion *region); /* exit is called when the region is hidden or removed */ void (*exit)(struct wmWindowManager *wm, struct ARegion *region); + /** + * Optional callback to decide whether the region should be treated as existing given the + * current context. When returning false, the region will be kept in storage, but is not + * available to the user in any way. Callbacks can assume that context has the owning area and + * space-data set. + */ + bool (*poll)(const RegionPollParams *params); /* draw entirely, view changes should be handled here */ void (*draw)(const struct bContext *C, struct ARegion *region); /** diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 643f046c574..c62443303f1 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -1203,7 +1203,8 @@ static void direct_link_region(BlendDataReader *reader, ARegion *region, int spa BLO_read_list(reader, ®ion->ui_lists); /* The area's search filter is runtime only, so we need to clear the active flag on read. */ - region->flag &= ~RGN_FLAG_SEARCH_FILTER_ACTIVE; + /* Clear runtime flags (e.g. search filter is runtime only). */ + region->flag &= ~(RGN_FLAG_SEARCH_FILTER_ACTIVE | RGN_FLAG_POLL_FAILED); LISTBASE_FOREACH (uiList *, ui_list, ®ion->ui_lists) { ui_list->type = NULL; diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 62751661645..ad7459e3d67 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -2223,6 +2223,69 @@ static void version_fix_image_format_copy(Main *bmain, ImageFormatData *format) } } +/** + * Some editors would manually manage visibility of regions, or lazy create them based on + * context. Ensure they are always there now, and use the new #ARegionType.poll(). + */ +static void version_ensure_missing_regions(ScrArea *area, SpaceLink *sl) +{ + ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase; + + switch (sl->spacetype) { + case SPACE_FILE: { + if (ARegion *ui_region = do_versions_add_region_if_not_found( + regionbase, RGN_TYPE_UI, "versioning: UI region for file", RGN_TYPE_TOOLS)) { + ui_region->alignment = RGN_ALIGN_TOP; + ui_region->flag |= RGN_FLAG_DYNAMIC_SIZE; + } + + if (ARegion *exec_region = do_versions_add_region_if_not_found( + regionbase, RGN_TYPE_EXECUTE, "versioning: execute region for file", RGN_TYPE_UI)) { + exec_region->alignment = RGN_ALIGN_BOTTOM; + exec_region->flag = RGN_FLAG_DYNAMIC_SIZE; + } + + if (ARegion *tool_props_region = do_versions_add_region_if_not_found( + regionbase, + RGN_TYPE_TOOL_PROPS, + "versioning: tool props region for file", + RGN_TYPE_EXECUTE)) { + tool_props_region->alignment = RGN_ALIGN_RIGHT; + tool_props_region->flag = RGN_FLAG_HIDDEN; + } + break; + } + case SPACE_CLIP: { + ARegion *region; + + region = do_versions_ensure_region( + regionbase, RGN_TYPE_UI, "versioning: properties region for clip", RGN_TYPE_HEADER); + region->alignment = RGN_ALIGN_RIGHT; + region->flag &= ~RGN_FLAG_HIDDEN; + + region = do_versions_ensure_region( + regionbase, RGN_TYPE_CHANNELS, "versioning: channels region for clip", RGN_TYPE_UI); + region->alignment = RGN_ALIGN_LEFT; + region->flag &= ~RGN_FLAG_HIDDEN; + region->v2d.scroll = V2D_SCROLL_BOTTOM; + region->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL; + + region = do_versions_ensure_region( + regionbase, RGN_TYPE_PREVIEW, "versioning: preview region for clip", RGN_TYPE_WINDOW); + region->flag &= ~RGN_FLAG_HIDDEN; + + break; + } + case SPACE_SEQ: { + do_versions_ensure_region(regionbase, + RGN_TYPE_CHANNELS, + "versioning: channels region for sequencer", + RGN_TYPE_TOOLS); + break; + } + } +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) { @@ -4190,5 +4253,35 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ + + /* Some regions used to be added/removed dynamically. Ensure they are always there, there is a + * `ARegionType.poll()` now. */ + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + version_ensure_missing_regions(area, sl); + + /* Ensure expected region state. Previously this was modified to hide/unhide regions. */ + + const ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : + &sl->regionbase; + if (sl->spacetype == SPACE_SEQ) { + ARegion *region_main = BKE_region_find_in_listbase_by_type(regionbase, + RGN_TYPE_WINDOW); + region_main->flag &= ~RGN_FLAG_HIDDEN; + region_main->alignment = RGN_ALIGN_NONE; + + ARegion *region_preview = BKE_region_find_in_listbase_by_type(regionbase, + RGN_TYPE_PREVIEW); + region_preview->flag &= ~RGN_FLAG_HIDDEN; + region_preview->alignment = RGN_ALIGN_NONE; + + ARegion *region_channels = BKE_region_find_in_listbase_by_type(regionbase, + RGN_TYPE_CHANNELS); + region_channels->alignment = RGN_ALIGN_LEFT; + } + } + } + } } } diff --git a/source/blender/blenloader/intern/versioning_common.cc b/source/blender/blenloader/intern/versioning_common.cc index 80df0a2ba74..31e8c7620dc 100644 --- a/source/blender/blenloader/intern/versioning_common.cc +++ b/source/blender/blenloader/intern/versioning_common.cc @@ -32,7 +32,7 @@ using blender::StringRef; ARegion *do_versions_add_region_if_not_found(ListBase *regionbase, int region_type, - const char *name, + const char *allocname, int link_after_region_type) { ARegion *link_after_region = nullptr; @@ -45,7 +45,28 @@ ARegion *do_versions_add_region_if_not_found(ListBase *regionbase, } } - ARegion *new_region = static_cast(MEM_callocN(sizeof(ARegion), name)); + ARegion *new_region = static_cast(MEM_callocN(sizeof(ARegion), allocname)); + new_region->regiontype = region_type; + BLI_insertlinkafter(regionbase, link_after_region, new_region); + return new_region; +} + +ARegion *do_versions_ensure_region(ListBase *regionbase, + int region_type, + const char *allocname, + int link_after_region_type) +{ + ARegion *link_after_region = nullptr; + LISTBASE_FOREACH (ARegion *, region, regionbase) { + if (region->regiontype == region_type) { + return region; + } + if (region->regiontype == link_after_region_type) { + link_after_region = region; + } + } + + ARegion *new_region = MEM_cnew(allocname); new_region->regiontype = region_type; BLI_insertlinkafter(regionbase, link_after_region, new_region); return new_region; diff --git a/source/blender/blenloader/intern/versioning_common.h b/source/blender/blenloader/intern/versioning_common.h index 40f383a27b2..8d17e9db39f 100644 --- a/source/blender/blenloader/intern/versioning_common.h +++ b/source/blender/blenloader/intern/versioning_common.h @@ -19,10 +19,24 @@ struct bNodeTree; extern "C" { #endif +/** + * Check if a region of type \a region_type exists in \a regionbase. Otherwise add it after the + * first region of type \a link_after_region_type. + * \returns null if a region of the given type already existed, otherwise the newly added region. + */ struct ARegion *do_versions_add_region_if_not_found(struct ListBase *regionbase, int region_type, - const char *name, + const char *allocname, int link_after_region_type); +/** + * Check if a region of type \a region_type exists in \a regionbase. Otherwise add it after the + * first region of type \a link_after_region_type. + * \returns either a new, or already existing region. + */ +ARegion *do_versions_ensure_region(ListBase *regionbase, + int region_type, + const char *allocname, + int link_after_region_type); /** * Rename if the ID doesn't exist. diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index dc14ee28b27..fae2d2067e1 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -292,7 +292,8 @@ void ED_screen_draw_edges(struct wmWindow *win); * for file read and first use, for scaling window, area moves. */ void ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win); -void ED_screen_ensure_updated(struct wmWindowManager *wm, +void ED_screen_ensure_updated(struct bContext *C, + struct wmWindowManager *wm, struct wmWindow *win, struct bScreen *screen); void ED_screen_do_listen(struct bContext *C, const struct wmNotifier *note); diff --git a/source/blender/editors/screen/area.cc b/source/blender/editors/screen/area.cc index 8fab06ddd3a..1b6cb2a80de 100644 --- a/source/blender/editors/screen/area.cc +++ b/source/blender/editors/screen/area.cc @@ -318,7 +318,7 @@ static void region_draw_azones(ScrArea *area, ARegion *region) area_draw_azone(az->x1, az->y1, az->x2, az->y2); } else if (az->type == AZONE_REGION) { - if (az->region) { + if (az->region && !(az->region->flag & RGN_FLAG_POLL_FAILED)) { /* only display tab or icons when the region is hidden */ if (az->region->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { region_draw_azone_tab_arrow(area, region, az); @@ -1005,6 +1005,10 @@ static void region_azone_tab_plus(ScrArea *area, AZone *az, ARegion *region) static bool region_azone_edge_poll(const ARegion *region, const bool is_fullscreen) { + if (region->flag & RGN_FLAG_POLL_FAILED) { + return false; + } + const bool is_hidden = (region->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); if (is_hidden && is_fullscreen) { @@ -1163,7 +1167,7 @@ static void region_overlap_fix(ScrArea *area, ARegion *region) int align1 = 0; const int align = RGN_ALIGN_ENUM_FROM_MASK(region->alignment); for (region_iter = region->prev; region_iter; region_iter = region_iter->prev) { - if (region_iter->flag & RGN_FLAG_HIDDEN) { + if (region_iter->flag & (RGN_FLAG_POLL_FAILED | RGN_FLAG_HIDDEN)) { continue; } @@ -1208,7 +1212,7 @@ static void region_overlap_fix(ScrArea *area, ARegion *region) /* At this point, 'region' is in its final position and still open. * Make a final check it does not overlap any previous 'other side' region. */ for (region_iter = region->prev; region_iter; region_iter = region_iter->prev) { - if (region_iter->flag & RGN_FLAG_HIDDEN) { + if (region_iter->flag & (RGN_FLAG_POLL_FAILED | RGN_FLAG_HIDDEN)) { continue; } if (ELEM(region_iter->alignment, RGN_ALIGN_FLOAT)) { @@ -1326,7 +1330,7 @@ static void region_rect_recursive( (region->sizey > 1 ? region->sizey + 0.5f : region->type->prefsizey); } - if (region->flag & RGN_FLAG_HIDDEN) { + if (region->flag & (RGN_FLAG_POLL_FAILED | RGN_FLAG_HIDDEN)) { /* hidden is user flag */ } else if (alignment == RGN_ALIGN_FLOAT) { @@ -1627,7 +1631,8 @@ static void area_calc_totrct(ScrArea *area, const rcti *window_rect) /* used for area initialize below */ static void region_subwindow(ARegion *region) { - bool hidden = (region->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) != 0; + bool hidden = (region->flag & (RGN_FLAG_POLL_FAILED | RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) != + 0; if ((region->alignment & RGN_SPLIT_PREV) && region->prev) { hidden = hidden || (region->prev->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); @@ -2072,7 +2077,7 @@ void ED_region_cursor_set(wmWindow *win, ScrArea *area, ARegion *region) void ED_region_visibility_change_update(bContext *C, ScrArea *area, ARegion *region) { - if (region->flag & RGN_FLAG_HIDDEN) { + if (region->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_POLL_FAILED)) { WM_event_remove_handlers(C, ®ion->handlers); /* Needed to close any open pop-overs which would otherwise remain open, * crashing on attempting to refresh. See: #93410. @@ -2182,6 +2187,10 @@ static void region_align_info_from_area(ScrArea *area, RegionTypeAlignInfo *r_al } LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (region->flag & RGN_FLAG_POLL_FAILED) { + continue; + } + const int index = region->regiontype; if (uint(index) < RGN_TYPE_NUM) { r_align_info->by_type[index].alignment = RGN_ALIGN_ENUM_FROM_MASK(region->alignment); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 7478a7a3573..88762a19778 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -713,8 +713,52 @@ void ED_screens_init(Main *bmain, wmWindowManager *wm) } } -void ED_screen_ensure_updated(wmWindowManager *wm, wmWindow *win, bScreen *screen) +static bool region_poll(const bScreen *screen, const ScrArea *area, const ARegion *region) { + if (!region->type || !region->type->poll) { + /* Show region by default. */ + return true; + } + + RegionPollParams params = {0}; + params.screen = screen; + params.area = area; + params.region = region; + + return region->type->poll(¶ms); +} + +static void screen_regions_poll(bContext *C, const wmWindow *win, bScreen *screen) +{ + bool any_changed = false; + ED_screen_areas_iter (win, screen, area) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + const int old_region_flag = region->flag; + + region->flag &= ~RGN_FLAG_POLL_FAILED; + + if (region_poll(screen, area, region) == false) { + region->flag |= RGN_FLAG_POLL_FAILED; + } + + if (old_region_flag != region->flag) { + any_changed = true; + + /* Enforce complete re-init. */ + region->v2d.flag &= ~V2D_IS_INIT; + ED_region_visibility_change_update(C, area, region); + } + } + } + + if (any_changed) { + screen->do_refresh = true; + } +} + +void ED_screen_ensure_updated(bContext *C, wmWindowManager *wm, wmWindow *win, bScreen *screen) +{ + screen_regions_poll(C, win, screen); if (screen->do_refresh) { ED_screen_refresh(wm, win); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7b6dba0f788..cc33c6b847c 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -5080,11 +5080,6 @@ static int userpref_show_exec(bContext *C, wmOperator *op) region->flag |= RGN_FLAG_HIDDEN; ED_region_visibility_change_update(C, area, region); - /* And also show the region with "Load & Save" buttons. */ - region = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE); - region->flag &= ~RGN_FLAG_HIDDEN; - ED_region_visibility_change_update(C, area, region); - return OPERATOR_FINISHED; } BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt index 5deab5dd368..7118722e1b7 100644 --- a/source/blender/editors/space_clip/CMakeLists.txt +++ b/source/blender/editors/space_clip/CMakeLists.txt @@ -34,7 +34,6 @@ set(SRC clip_graph_draw.cc clip_graph_ops.cc clip_ops.cc - clip_toolbar.cc clip_utils.cc space_clip.cc tracking_ops.cc diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index 5b0d669093c..f939782c930 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -114,10 +114,6 @@ void CLIP_OT_cursor_set(struct wmOperatorType *ot); void CLIP_OT_lock_selection_toggle(struct wmOperatorType *ot); -/* clip_toolbar.cc */ - -struct ARegion *ED_clip_has_properties_region(struct ScrArea *area); - /* clip_utils.cc */ typedef enum { diff --git a/source/blender/editors/space_clip/clip_toolbar.cc b/source/blender/editors/space_clip/clip_toolbar.cc deleted file mode 100644 index 1c3d034a5c0..00000000000 --- a/source/blender/editors/space_clip/clip_toolbar.cc +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2011 Blender Foundation */ - -/** \file - * \ingroup spclip - */ - -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - -#include "BKE_context.h" -#include "BKE_screen.h" - -#include "WM_types.h" - -#include "ED_screen.h" - -#include "clip_intern.h" /* own include */ - -/* ************************ header area region *********************** */ - -/************************** properties ******************************/ - -ARegion *ED_clip_has_properties_region(ScrArea *area) -{ - ARegion *region, *arnew; - - region = BKE_area_find_region_type(area, RGN_TYPE_UI); - if (region) { - return region; - } - - /* add subdiv level; after header */ - region = BKE_area_find_region_type(area, RGN_TYPE_HEADER); - - /* is error! */ - if (region == nullptr) { - return nullptr; - } - - arnew = MEM_cnew("clip properties region"); - - BLI_insertlinkafter(&area->regionbase, region, arnew); - arnew->regiontype = RGN_TYPE_UI; - arnew->alignment = RGN_ALIGN_RIGHT; - - arnew->flag = RGN_FLAG_HIDDEN; - - return arnew; -} diff --git a/source/blender/editors/space_clip/space_clip.cc b/source/blender/editors/space_clip/space_clip.cc index 7005be7b5dd..5543730ec19 100644 --- a/source/blender/editors/space_clip/space_clip.cc +++ b/source/blender/editors/space_clip/space_clip.cc @@ -60,10 +60,6 @@ static void init_preview_region(const Scene *scene, const SpaceClip *sc, ARegion *region) { - region->regiontype = RGN_TYPE_PREVIEW; - region->alignment = RGN_ALIGN_TOP; - region->flag |= RGN_FLAG_HIDDEN; - if (sc->view == SC_VIEW_DOPESHEET) { region->v2d.tot.xmin = -10.0f; region->v2d.tot.ymin = float(-area->winy) / 3.0f; @@ -115,78 +111,6 @@ static void init_preview_region(const Scene *scene, } } -static void reinit_preview_region(const bContext *C, ARegion *region) -{ - Scene *scene = CTX_data_scene(C); - ScrArea *area = CTX_wm_area(C); - SpaceClip *sc = CTX_wm_space_clip(C); - - if (sc->view == SC_VIEW_DOPESHEET) { - if ((region->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) == 0) { - init_preview_region(scene, area, sc, region); - } - } - else { - if (region->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) { - init_preview_region(scene, area, sc, region); - } - } -} - -static ARegion *ED_clip_has_preview_region(const bContext *C, ScrArea *area) -{ - ARegion *region, *arnew; - - region = BKE_area_find_region_type(area, RGN_TYPE_PREVIEW); - if (region) { - return region; - } - - /* add subdiv level; after header */ - region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); - - /* is error! */ - if (region == nullptr) { - return nullptr; - } - - arnew = MEM_cnew("clip preview region"); - - BLI_insertlinkbefore(&area->regionbase, region, arnew); - init_preview_region(CTX_data_scene(C), area, CTX_wm_space_clip(C), arnew); - - return arnew; -} - -static ARegion *ED_clip_has_channels_region(ScrArea *area) -{ - ARegion *region, *arnew; - - region = BKE_area_find_region_type(area, RGN_TYPE_CHANNELS); - if (region) { - return region; - } - - /* add subdiv level; after header */ - region = BKE_area_find_region_type(area, RGN_TYPE_PREVIEW); - - /* is error! */ - if (region == nullptr) { - return nullptr; - } - - arnew = MEM_cnew("clip channels region"); - - BLI_insertlinkbefore(&area->regionbase, region, arnew); - arnew->regiontype = RGN_TYPE_CHANNELS; - arnew->alignment = RGN_ALIGN_LEFT; - - arnew->v2d.scroll = V2D_SCROLL_BOTTOM; - arnew->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL; - - return arnew; -} - static void clip_scopes_tag_refresh(ScrArea *area) { SpaceClip *sc = (SpaceClip *)area->spacedata.first; @@ -222,7 +146,7 @@ static void clip_area_sync_frame_from_scene(ScrArea *area, const Scene *scene) /* ******************** default callbacks for clip space ***************** */ -static SpaceLink *clip_create(const ScrArea *area, const Scene *scene) +static SpaceLink *clip_create(const ScrArea * /*area*/, const Scene * /*scene*/) { ARegion *region; SpaceClip *sc; @@ -264,7 +188,7 @@ static SpaceLink *clip_create(const ScrArea *area, const Scene *scene) region = MEM_cnew("preview for clip"); BLI_addtail(&sc->regionbase, region); - init_preview_region(scene, area, sc, region); + region->regiontype = RGN_TYPE_PREVIEW; /* main region */ region = MEM_cnew("main region for clip"); @@ -620,99 +544,28 @@ static void clip_dropboxes(void) WM_dropbox_add(lb, "CLIP_OT_open", clip_drop_poll, clip_drop_copy, nullptr, nullptr); } -static bool clip_set_region_visible(const bContext *C, - ARegion *region, - const bool is_visible, - const short alignment, - const bool view_all_on_show) +static void clip_refresh(const bContext *C, ScrArea *area) { - bool view_changed = false; + Scene *scene = CTX_data_scene(C); + SpaceClip *sc = (SpaceClip *)area->spacedata.first; - if (is_visible) { - if (region && (region->flag & RGN_FLAG_HIDDEN)) { - region->flag &= ~RGN_FLAG_HIDDEN; - region->v2d.flag &= ~V2D_IS_INIT; - if (view_all_on_show) { - region->v2d.cur = region->v2d.tot; - } - view_changed = true; - } - if (region && region->alignment != alignment) { - region->alignment = alignment; - view_changed = true; + ARegion *region_preview = BKE_area_find_region_type(area, RGN_TYPE_PREVIEW); + if (!(region_preview->v2d.flag & V2D_IS_INIT)) { + init_preview_region(scene, area, sc, region_preview); + region_preview->v2d.cur = region_preview->v2d.tot; + } + /* #V2D_VIEWSYNC_AREA_VERTICAL must always be set for the dopesheet view, in graph view it must + * be unset. This is enforced by region re-initialization. + * That means if it's not set correctly, the view just changed and needs re-initialization */ + else if (sc->view == SC_VIEW_DOPESHEET) { + if ((region_preview->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) == 0) { + init_preview_region(scene, area, sc, region_preview); } } else { - if (region && !(region->flag & RGN_FLAG_HIDDEN)) { - region->flag |= RGN_FLAG_HIDDEN; - region->v2d.flag &= ~V2D_IS_INIT; - WM_event_remove_handlers((bContext *)C, ®ion->handlers); - view_changed = true; + if (region_preview->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) { + init_preview_region(scene, area, sc, region_preview); } - if (region && region->alignment != RGN_ALIGN_NONE) { - region->alignment = RGN_ALIGN_NONE; - view_changed = true; - } - } - - return view_changed; -} - -static void clip_refresh(const bContext *C, ScrArea *area) -{ - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *window = CTX_wm_window(C); - Scene *scene = CTX_data_scene(C); - SpaceClip *sc = (SpaceClip *)area->spacedata.first; - ARegion *region_main = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); - ARegion *region_tools = BKE_area_find_region_type(area, RGN_TYPE_TOOLS); - ARegion *region_preview = ED_clip_has_preview_region(C, area); - ARegion *region_properties = ED_clip_has_properties_region(area); - ARegion *region_channels = ED_clip_has_channels_region(area); - bool main_visible = false, preview_visible = false, tools_visible = false; - bool properties_visible = false, channels_visible = false; - bool view_changed = false; - - switch (sc->view) { - case SC_VIEW_CLIP: - main_visible = true; - preview_visible = false; - tools_visible = true; - properties_visible = true; - channels_visible = false; - break; - case SC_VIEW_GRAPH: - main_visible = false; - preview_visible = true; - tools_visible = false; - properties_visible = false; - channels_visible = false; - - reinit_preview_region(C, region_preview); - break; - case SC_VIEW_DOPESHEET: - main_visible = false; - preview_visible = true; - tools_visible = false; - properties_visible = false; - channels_visible = true; - - reinit_preview_region(C, region_preview); - break; - } - - view_changed |= clip_set_region_visible(C, region_main, main_visible, RGN_ALIGN_NONE, false); - view_changed |= clip_set_region_visible( - C, region_properties, properties_visible, RGN_ALIGN_RIGHT, false); - view_changed |= clip_set_region_visible(C, region_tools, tools_visible, RGN_ALIGN_LEFT, false); - view_changed |= clip_set_region_visible( - C, region_preview, preview_visible, RGN_ALIGN_NONE, true); - view_changed |= clip_set_region_visible( - C, region_channels, channels_visible, RGN_ALIGN_LEFT, false); - - if (view_changed) { - ED_area_init(wm, window, area); - ED_area_tag_redraw(area); } BKE_movieclip_user_set_frame(&sc->user, scene->r.cfra); @@ -780,6 +633,12 @@ static void movieclip_main_area_set_view2d(const bContext *C, ARegion *region) region->v2d.cur.ymax /= h; } +static bool clip_main_region_poll(const RegionPollParams *params) +{ + const SpaceClip *sclip = static_cast(params->area->spacedata.first); + return ELEM(sclip->view, SC_VIEW_CLIP); +} + /* add handlers, stuff you only do once or on area/region changes */ static void clip_main_region_init(wmWindowManager *wm, ARegion *region) { @@ -935,6 +794,12 @@ static void clip_main_region_listener(const wmRegionListenerParams *params) /****************** preview region ******************/ +static bool clip_preview_region_poll(const RegionPollParams *params) +{ + const SpaceClip *sclip = static_cast(params->area->spacedata.first); + return ELEM(sclip->view, SC_VIEW_GRAPH, SC_VIEW_DOPESHEET); +} + static void clip_preview_region_init(wmWindowManager *wm, ARegion *region) { wmKeyMap *keymap; @@ -1060,6 +925,12 @@ static void clip_preview_region_listener(const wmRegionListenerParams * /*params /****************** channels region ******************/ +static bool clip_channels_region_poll(const RegionPollParams *params) +{ + const SpaceClip *sclip = static_cast(params->area->spacedata.first); + return ELEM(sclip->view, SC_VIEW_DOPESHEET); +} + static void clip_channels_region_init(wmWindowManager *wm, ARegion *region) { wmKeyMap *keymap; @@ -1134,6 +1005,12 @@ static void clip_header_region_listener(const wmRegionListenerParams *params) /****************** tools region ******************/ +static bool clip_tools_region_poll(const RegionPollParams *params) +{ + const SpaceClip *sclip = static_cast(params->area->spacedata.first); + return ELEM(sclip->view, SC_VIEW_CLIP); +} + /* add handlers, stuff you only do once or on area/region changes */ static void clip_tools_region_init(wmWindowManager *wm, ARegion *region) { @@ -1184,6 +1061,12 @@ static void clip_props_region_listener(const wmRegionListenerParams *params) /****************** properties region ******************/ +static bool clip_properties_region_poll(const RegionPollParams *params) +{ + const SpaceClip *sclip = static_cast(params->area->spacedata.first); + return ELEM(sclip->view, SC_VIEW_CLIP); +} + /* add handlers, stuff you only do once or on area/region changes */ static void clip_properties_region_init(wmWindowManager *wm, ARegion *region) { @@ -1286,6 +1169,7 @@ void ED_spacetype_clip(void) /* regions: main window */ art = MEM_cnew("spacetype clip region"); art->regionid = RGN_TYPE_WINDOW; + art->poll = clip_main_region_poll; art->init = clip_main_region_init; art->draw = clip_main_region_draw; art->listener = clip_main_region_listener; @@ -1297,6 +1181,7 @@ void ED_spacetype_clip(void) art = MEM_cnew("spacetype clip region preview"); art->regionid = RGN_TYPE_PREVIEW; art->prefsizey = 240; + art->poll = clip_preview_region_poll; art->init = clip_preview_region_init; art->draw = clip_preview_region_draw; art->listener = clip_preview_region_listener; @@ -1309,6 +1194,7 @@ void ED_spacetype_clip(void) art->regionid = RGN_TYPE_UI; art->prefsizex = UI_SIDEBAR_PANEL_WIDTH; art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI; + art->poll = clip_properties_region_poll; art->init = clip_properties_region_init; art->draw = clip_properties_region_draw; art->listener = clip_properties_region_listener; @@ -1320,6 +1206,7 @@ void ED_spacetype_clip(void) art->regionid = RGN_TYPE_TOOLS; art->prefsizex = UI_SIDEBAR_PANEL_WIDTH; art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI; + art->poll = clip_tools_region_poll; art->listener = clip_props_region_listener; art->init = clip_tools_region_init; art->draw = clip_tools_region_draw; @@ -1345,6 +1232,7 @@ void ED_spacetype_clip(void) art->regionid = RGN_TYPE_CHANNELS; art->prefsizex = UI_COMPACT_PANEL_WIDTH; art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI; + art->poll = clip_channels_region_poll; art->listener = clip_channels_region_listener; art->init = clip_channels_region_init; art->draw = clip_channels_region_draw; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 873bae7604c..019f1fdbccb 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -49,60 +49,9 @@ #include "filelist.h" #include "fsmenu.h" -static ARegion *file_ui_region_ensure(ScrArea *area, ARegion *region_prev) -{ - ARegion *region; - - if ((region = BKE_area_find_region_type(area, RGN_TYPE_UI)) != NULL) { - return region; - } - - region = MEM_callocN(sizeof(ARegion), "execute region for file"); - BLI_insertlinkafter(&area->regionbase, region_prev, region); - region->regiontype = RGN_TYPE_UI; - region->alignment = RGN_ALIGN_TOP; - region->flag = RGN_FLAG_DYNAMIC_SIZE; - - return region; -} - -static ARegion *file_execute_region_ensure(ScrArea *area, ARegion *region_prev) -{ - ARegion *region; - - if ((region = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE)) != NULL) { - return region; - } - - region = MEM_callocN(sizeof(ARegion), "execute region for file"); - BLI_insertlinkafter(&area->regionbase, region_prev, region); - region->regiontype = RGN_TYPE_EXECUTE; - region->alignment = RGN_ALIGN_BOTTOM; - region->flag = RGN_FLAG_DYNAMIC_SIZE; - - return region; -} - -static ARegion *file_tool_props_region_ensure(ScrArea *area, ARegion *region_prev) -{ - ARegion *region; - - if ((region = BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS)) != NULL) { - return region; - } - - /* add subdiv level; after execute region */ - region = MEM_callocN(sizeof(ARegion), "tool props for file"); - BLI_insertlinkafter(&area->regionbase, region_prev, region); - region->regiontype = RGN_TYPE_TOOL_PROPS; - region->alignment = RGN_ALIGN_RIGHT; - region->flag = RGN_FLAG_HIDDEN; - - return region; -} - /* ******************** default callbacks for file space ***************** */ +/* TODO create regions in versioning? */ static SpaceLink *file_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; @@ -129,9 +78,21 @@ static SpaceLink *file_create(const ScrArea *UNUSED(area), const Scene *UNUSED(s BLI_addtail(&sfile->regionbase, region); region->regiontype = RGN_TYPE_UI; region->alignment = RGN_ALIGN_TOP; - region->flag |= RGN_FLAG_DYNAMIC_SIZE; + region->flag = RGN_FLAG_DYNAMIC_SIZE; - /* Tool props and execute region are added as needed, see file_refresh(). */ + /* execute region */ + region = MEM_callocN(sizeof(ARegion), "execute region for file"); + BLI_addtail(&sfile->regionbase, region); + region->regiontype = RGN_TYPE_EXECUTE; + region->alignment = RGN_ALIGN_BOTTOM; + region->flag = RGN_FLAG_DYNAMIC_SIZE; + + /* tools props region */ + region = MEM_callocN(sizeof(ARegion), "tool props for file"); + BLI_addtail(&sfile->regionbase, region); + region->regiontype = RGN_TYPE_TOOL_PROPS; + region->alignment = RGN_ALIGN_RIGHT; + region->flag = RGN_FLAG_HIDDEN; /* main region */ region = MEM_callocN(sizeof(ARegion), "main region for file"); @@ -231,69 +192,6 @@ static SpaceLink *file_duplicate(SpaceLink *sl) return (SpaceLink *)sfilen; } -static void file_ensure_valid_region_state(bContext *C, - wmWindowManager *wm, - wmWindow *win, - ScrArea *area, - SpaceFile *sfile, - FileSelectParams *params) -{ - ARegion *region_tools = BKE_area_find_region_type(area, RGN_TYPE_TOOLS); - bool needs_init = false; /* To avoid multiple ED_area_init() calls. */ - - BLI_assert(region_tools); - - if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) { - file_tool_props_region_ensure(area, region_tools); - - ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE); - if (region_execute) { - ED_region_remove(C, area, region_execute); - needs_init = true; - } - ARegion *region_ui = BKE_area_find_region_type(area, RGN_TYPE_UI); - if (region_ui) { - ED_region_remove(C, area, region_ui); - needs_init = true; - } - } - /* If there's an file-operation, ensure we have the option and execute region */ - else if (sfile->op && !BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS)) { - ARegion *region_ui = file_ui_region_ensure(area, region_tools); - ARegion *region_execute = file_execute_region_ensure(area, region_ui); - ARegion *region_props = file_tool_props_region_ensure(area, region_execute); - - if (params->flag & FILE_HIDE_TOOL_PROPS) { - region_props->flag |= RGN_FLAG_HIDDEN; - } - else { - region_props->flag &= ~RGN_FLAG_HIDDEN; - } - - needs_init = true; - } - /* If there's _no_ file-operation, ensure we _don't_ have the option and execute region */ - else if (!sfile->op) { - ARegion *region_props = BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS); - ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE); - ARegion *region_ui = file_ui_region_ensure(area, region_tools); - UNUSED_VARS(region_ui); - - if (region_execute) { - ED_region_remove(C, area, region_execute); - needs_init = true; - } - if (region_props) { - ED_region_remove(C, area, region_props); - needs_init = true; - } - } - - if (needs_init) { - ED_area_init(wm, win, area); - } -} - static void file_refresh(const bContext *C, ScrArea *area) { wmWindowManager *wm = CTX_wm_manager(C); @@ -389,9 +287,26 @@ static void file_refresh(const bContext *C, ScrArea *area) sfile->layout->dirty = true; } - /* Might be called with NULL area, see file_main_region_draw() below. */ if (area) { - file_ensure_valid_region_state((bContext *)C, wm, win, area, sfile, params); + ARegion *region_props = BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS); + const bool region_flag_old = region_props->flag; + if (!(region_props->v2d.flag & V2D_IS_INIT)) { + if (ED_fileselect_is_asset_browser(sfile)) { + /* Hide by default in asset browser. */ + region_props->flag |= RGN_FLAG_HIDDEN; + } + else { + if (params->flag & FILE_HIDE_TOOL_PROPS) { + region_props->flag |= RGN_FLAG_HIDDEN; + } + else { + region_props->flag &= ~RGN_FLAG_HIDDEN; + } + } + } + if (region_flag_old != region_props->flag) { + ED_region_visibility_change_update((bContext *)C, area, region_props); + } } ED_area_tag_redraw(area); @@ -714,6 +629,25 @@ static void file_keymap(struct wmKeyConfig *keyconf) WM_keymap_ensure(keyconf, "File Browser Buttons", SPACE_FILE, 0); } +static bool file_ui_region_poll(const RegionPollParams *params) +{ + const SpaceFile *sfile = (SpaceFile *)params->area->spacedata.first; + /* Always visible except when browsing assets. */ + return sfile->browse_mode != FILE_BROWSE_MODE_ASSETS; +} + +static bool file_tool_props_region_poll(const RegionPollParams *params) +{ + const SpaceFile *sfile = (SpaceFile *)params->area->spacedata.first; + return (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) || (sfile->op != NULL); +} + +static bool file_execution_region_poll(const RegionPollParams *params) +{ + const SpaceFile *sfile = (SpaceFile *)params->area->spacedata.first; + return sfile->op != NULL; +} + static void file_tools_region_init(wmWindowManager *wm, ARegion *region) { wmKeyMap *keymap; @@ -869,6 +803,10 @@ static int file_space_subtype_get(ScrArea *area) static void file_space_subtype_set(ScrArea *area, int value) { SpaceFile *sfile = area->spacedata.first; + /* Force re-init. */ + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + region->v2d.flag &= ~V2D_IS_INIT; + } sfile->browse_mode = value; } @@ -1085,6 +1023,7 @@ void ED_spacetype_file(void) art = MEM_callocN(sizeof(ARegionType), "spacetype file region"); art->regionid = RGN_TYPE_UI; art->keymapflag = ED_KEYMAP_UI; + art->poll = file_ui_region_poll; art->listener = file_ui_region_listener; art->init = file_ui_region_init; art->draw = file_ui_region_draw; @@ -1094,6 +1033,7 @@ void ED_spacetype_file(void) art = MEM_callocN(sizeof(ARegionType), "spacetype file region"); art->regionid = RGN_TYPE_EXECUTE; art->keymapflag = ED_KEYMAP_UI; + art->poll = file_execution_region_poll; art->listener = file_ui_region_listener; art->init = file_execution_region_init; art->draw = file_execution_region_draw; @@ -1118,6 +1058,7 @@ void ED_spacetype_file(void) art->prefsizex = 240; art->prefsizey = 60; art->keymapflag = ED_KEYMAP_UI; + art->poll = file_tool_props_region_poll; art->listener = file_tool_props_region_listener; art->init = file_tools_region_init; art->draw = file_tools_region_draw; diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 8bd975e30ce..ea34b92fe2a 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -144,7 +144,6 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce BLI_addtail(&sseq->regionbase, region); region->regiontype = RGN_TYPE_PREVIEW; region->alignment = RGN_ALIGN_TOP; - region->flag |= RGN_FLAG_HIDDEN; /* For now, aspect ratio should be maintained, and zoom is clamped within sane default limits. */ region->v2d.keepzoom = V2D_KEEPASPECT | V2D_KEEPZOOM | V2D_LIMITZOOM; region->v2d.minzoom = 0.001f; @@ -244,107 +243,46 @@ static void sequencer_refresh(const bContext *C, ScrArea *area) bool view_changed = false; switch (sseq->view) { - case SEQ_VIEW_SEQUENCE: - if (region_main && (region_main->flag & RGN_FLAG_HIDDEN)) { - region_main->flag &= ~RGN_FLAG_HIDDEN; - region_main->v2d.flag &= ~V2D_IS_INIT; - view_changed = true; - } - if (region_preview && !(region_preview->flag & RGN_FLAG_HIDDEN)) { - region_preview->flag |= RGN_FLAG_HIDDEN; - region_preview->v2d.flag &= ~V2D_IS_INIT; - WM_event_remove_handlers((bContext *)C, ®ion_preview->handlers); - view_changed = true; - } - if (region_main && region_main->alignment != RGN_ALIGN_NONE) { - region_main->alignment = RGN_ALIGN_NONE; - view_changed = true; - } - if (region_preview && region_preview->alignment != RGN_ALIGN_NONE) { - region_preview->alignment = RGN_ALIGN_NONE; - view_changed = true; - } - break; case SEQ_VIEW_PREVIEW: - if (region_main && !(region_main->flag & RGN_FLAG_HIDDEN)) { - region_main->flag |= RGN_FLAG_HIDDEN; - region_main->v2d.flag &= ~V2D_IS_INIT; - WM_event_remove_handlers((bContext *)C, ®ion_main->handlers); - view_changed = true; - } - if (region_preview && (region_preview->flag & RGN_FLAG_HIDDEN)) { - region_preview->flag &= ~RGN_FLAG_HIDDEN; - region_preview->v2d.flag &= ~V2D_IS_INIT; + /* Reset scrolling when preview region just appears. */ + if (!(region_preview->v2d.flag & V2D_IS_INIT)) { region_preview->v2d.cur = region_preview->v2d.tot; - view_changed = true; + /* Only redraw, don't re-init. */ + ED_area_tag_redraw(area); } - if (region_main && region_main->alignment != RGN_ALIGN_NONE) { - region_main->alignment = RGN_ALIGN_NONE; - view_changed = true; - } - if (region_preview && region_preview->alignment != RGN_ALIGN_NONE) { + if (region_preview->alignment != RGN_ALIGN_NONE) { region_preview->alignment = RGN_ALIGN_NONE; view_changed = true; } break; - case SEQ_VIEW_SEQUENCE_PREVIEW: - if (region_main && region_preview) { - /* Get available height (without DPI correction). */ - const float height = (area->winy - ED_area_headersize()) / UI_SCALE_FAC; + case SEQ_VIEW_SEQUENCE_PREVIEW: { + /* Get available height (without DPI correction). */ + const float height = (area->winy - ED_area_headersize()) / UI_SCALE_FAC; - /* We reuse hidden region's size, allows to find same layout as before if we just switch - * between one 'full window' view and the combined one. This gets lost if we switch to both - * 'full window' views before, though... Better than nothing. */ - if (region_main->flag & RGN_FLAG_HIDDEN) { - region_main->flag &= ~RGN_FLAG_HIDDEN; - region_main->v2d.flag &= ~V2D_IS_INIT; - region_preview->sizey = (int)(height - region_main->sizey); - view_changed = true; - } - if (region_preview->flag & RGN_FLAG_HIDDEN) { - region_preview->flag &= ~RGN_FLAG_HIDDEN; - region_preview->v2d.flag &= ~V2D_IS_INIT; - region_preview->v2d.cur = region_preview->v2d.tot; - region_main->sizey = (int)(height - region_preview->sizey); - view_changed = true; - } - if (region_main->alignment != RGN_ALIGN_NONE) { - region_main->alignment = RGN_ALIGN_NONE; - view_changed = true; - } - if (region_preview->alignment != RGN_ALIGN_TOP) { - region_preview->alignment = RGN_ALIGN_TOP; - view_changed = true; - } - /* Final check that both preview and main height are reasonable. */ - if (region_preview->sizey < 10 || region_main->sizey < 10 || - region_preview->sizey + region_main->sizey > height) { - region_preview->sizey = roundf(height * 0.4f); - region_main->sizey = (int)(height - region_preview->sizey); - view_changed = true; - } + /* We reuse hidden region's size, allows to find same layout as before if we just switch + * between one 'full window' view and the combined one. This gets lost if we switch to both + * 'full window' views before, though... Better than nothing. */ + if (!(region_preview->v2d.flag & V2D_IS_INIT)) { + region_preview->v2d.cur = region_preview->v2d.tot; + region_main->sizey = (int)(height - region_preview->sizey); + region_preview->sizey = (int)(height - region_main->sizey); + view_changed = true; + } + if (region_preview->alignment != RGN_ALIGN_TOP) { + region_preview->alignment = RGN_ALIGN_TOP; + view_changed = true; + } + /* Final check that both preview and main height are reasonable. */ + if (region_preview->sizey < 10 || region_main->sizey < 10 || + region_preview->sizey + region_main->sizey > height) { + region_preview->sizey = roundf(height * 0.4f); + region_main->sizey = (int)(height - region_preview->sizey); + view_changed = true; } break; - } - - ARegion *region_channels = sequencer_find_region(area, RGN_TYPE_CHANNELS); - if (sseq->view == SEQ_VIEW_SEQUENCE) { - if (region_channels && region_channels->alignment != RGN_ALIGN_LEFT) { - region_channels->alignment = RGN_ALIGN_LEFT; - view_changed = true; - } - } - else { - if (region_channels && !(region_channels->flag & RGN_FLAG_HIDDEN)) { - region_channels->flag |= RGN_FLAG_HIDDEN; - region_channels->v2d.flag &= ~V2D_IS_INIT; - WM_event_remove_handlers((bContext *)C, ®ion_channels->handlers); - view_changed = true; - } - if (region_channels && region_channels->alignment != RGN_ALIGN_NONE) { - region_channels->alignment = RGN_ALIGN_NONE; - view_changed = true; } + case SEQ_VIEW_SEQUENCE: + break; } if (view_changed) { @@ -501,6 +439,13 @@ static void sequencer_gizmos(void) } /* *********************** sequencer (main) region ************************ */ + +static bool sequencer_main_region_poll(const RegionPollParams *params) +{ + const SpaceSeq *sseq = (SpaceSeq *)params->area->spacedata.first; + return ELEM(sseq->view, SEQ_VIEW_SEQUENCE, SEQ_VIEW_SEQUENCE_PREVIEW); +} + /* Add handlers, stuff you only do once or on area/region changes. */ static void sequencer_main_region_init(wmWindowManager *wm, ARegion *region) { @@ -754,6 +699,13 @@ static void sequencer_tools_region_draw(const bContext *C, ARegion *region) ED_region_panels(C, region); } /* *********************** preview region ************************ */ + +static bool sequencer_preview_region_poll(const RegionPollParams *params) +{ + const SpaceSeq *sseq = (SpaceSeq *)params->area->spacedata.first; + return ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW); +} + static void sequencer_preview_region_init(wmWindowManager *wm, ARegion *region) { wmKeyMap *keymap; @@ -976,6 +928,12 @@ static void sequencer_id_remap(ScrArea *UNUSED(area), /* ************************************* */ +static bool sequencer_channel_region_poll(const RegionPollParams *params) +{ + const SpaceSeq *sseq = (SpaceSeq *)params->area->spacedata.first; + return ELEM(sseq->view, SEQ_VIEW_SEQUENCE); +} + /* add handlers, stuff you only do once or on area/region changes */ static void sequencer_channel_region_init(wmWindowManager *wm, ARegion *region) { @@ -1063,6 +1021,7 @@ void ED_spacetype_sequencer(void) /* Main window. */ art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); art->regionid = RGN_TYPE_WINDOW; + art->poll = sequencer_main_region_poll; art->init = sequencer_main_region_init; art->draw = sequencer_main_region_draw; art->draw_overlay = sequencer_main_region_draw_overlay; @@ -1077,6 +1036,7 @@ void ED_spacetype_sequencer(void) /* Preview. */ art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); art->regionid = RGN_TYPE_PREVIEW; + art->poll = sequencer_preview_region_poll; art->init = sequencer_preview_region_init; art->layout = sequencer_preview_region_layout; art->on_view2d_changed = sequencer_preview_region_view2d_changed; @@ -1115,6 +1075,7 @@ void ED_spacetype_sequencer(void) art->regionid = RGN_TYPE_CHANNELS; art->prefsizex = UI_COMPACT_PANEL_WIDTH; art->keymapflag = ED_KEYMAP_UI; + art->poll = sequencer_channel_region_poll; art->init = sequencer_channel_region_init; art->draw = sequencer_channel_region_draw; art->listener = sequencer_main_region_listener; diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c index 8471781cf20..f8d31d5e70a 100644 --- a/source/blender/editors/space_userpref/space_userpref.c +++ b/source/blender/editors/space_userpref/space_userpref.c @@ -65,7 +65,7 @@ static SpaceLink *userpref_create(const ScrArea *area, const Scene *UNUSED(scene BLI_addtail(&spref->regionbase, region); region->regiontype = RGN_TYPE_EXECUTE; region->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV; - region->flag |= RGN_FLAG_DYNAMIC_SIZE | RGN_FLAG_HIDDEN; + region->flag |= RGN_FLAG_DYNAMIC_SIZE; /* main region */ region = MEM_callocN(sizeof(ARegion), "main region for userpref"); @@ -156,6 +156,12 @@ static void userpref_navigation_region_draw(const bContext *C, ARegion *region) ED_region_panels(C, region); } +static bool userpref_execute_region_poll(const RegionPollParams *params) +{ + const ARegion *region_header = BKE_area_find_region_type(params->area, RGN_TYPE_HEADER); + return !region_header->visible; +} + /* add handlers, stuff you only do once or on area/region changes */ static void userpref_execute_region_init(wmWindowManager *wm, ARegion *region) { @@ -229,6 +235,7 @@ void ED_spacetype_userpref(void) art = MEM_callocN(sizeof(ARegionType), "spacetype userpref region"); art->regionid = RGN_TYPE_EXECUTE; art->prefsizey = HEADERY; + art->poll = userpref_execute_region_poll; art->init = userpref_execute_region_init; art->layout = ED_region_panels_layout; art->draw = ED_region_panels_draw; diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index cc7360ae6a4..1fb64e7540e 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -725,6 +725,9 @@ enum { * region's layout pass. so that expansion is still interactive, */ RGN_FLAG_SEARCH_FILTER_UPDATE = (1 << 9), + /** #ARegionType.poll() failed for the current context, and the region should be treated as if it + * wouldn't exist. Runtime only flag. */ + RGN_FLAG_POLL_FAILED = (1 << 10), }; /** #ARegion.do_draw */ diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index c1129cf150a..1f8b434d08d 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -895,6 +895,9 @@ static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo) /* Compute UI layouts for dynamically size regions. */ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (region->flag & RGN_FLAG_POLL_FAILED) { + continue; + } /* Dynamic region may have been flagged as too small because their size on init is 0. * ARegion.visible is false then, as expected. The layout should still be created then, so * the region size can be updated (it may turn out to be not too small then). */ @@ -1380,7 +1383,7 @@ void wm_draw_update(bContext *C) wm_window_make_drawable(wm, win); /* notifiers for screen redraw */ - ED_screen_ensure_updated(wm, win, screen); + ED_screen_ensure_updated(C, wm, win, screen); wm_draw_window(C, win); wm_draw_update_clear_window(C, win);