UI: Region polling support #105088

Merged
Julian Eisel merged 39 commits from JulianEisel/blender:temp-region-poll into main 2023-04-05 15:30:46 +02:00
18 changed files with 390 additions and 453 deletions

View File

@ -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 */
Review

Doesn't seem like a real issue, for the majority of regions there is no poll function and so region_poll() early exists before any context access. But sure, easy enough of a change.

Doesn't seem like a real issue, for the majority of regions there is no poll function and so `region_poll()` early exists before any context access. But sure, easy enough of a change.
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);
/**

View File

@ -1203,7 +1203,8 @@ static void direct_link_region(BlendDataReader *reader, ARegion *region, int spa
BLO_read_list(reader, &region->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, &region->ui_lists) {
ui_list->type = NULL;

View File

@ -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;
}
}
}
}
}
}

View File

@ -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<ARegion *>(MEM_callocN(sizeof(ARegion), name));
ARegion *new_region = static_cast<ARegion *>(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,
Review

Do we really need to pass a name for the allocation here? Are we finding memory leaks that aren't easily found with ASAN nowadays?

Do we really need to pass a name for the allocation here? Are we finding memory leaks that aren't easily found with ASAN nowadays?
Review

I think it's useful. I use it fairly often, and not everybody has ASan enabled. But sure, with ASan you don't need it I guess.

I think it's useful. I use it fairly often, and not everybody has ASan enabled. But sure, with ASan you don't need it I guess.
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<ARegion>(allocname);
new_region->regiontype = region_type;
BLI_insertlinkafter(regionbase, link_after_region, new_region);
return new_region;

View File

@ -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.

View File

@ -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);

View File

@ -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, &region->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);

View File

@ -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(&params);
}
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);
}

View File

@ -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!");

View File

@ -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

View File

@ -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 {

View File

@ -1,54 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2011 Blender Foundation */
/** \file
* \ingroup spclip
*/
#include <string.h>
#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<ARegion>("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;
}

View File

@ -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<ARegion>("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<ARegion>("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<ARegion>("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<ARegion>("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, &region->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<SpaceClip *>(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<SpaceClip *>(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<SpaceClip *>(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<SpaceClip *>(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<SpaceClip *>(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<ARegionType>("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<ARegionType>("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;

View File

@ -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;

View File

@ -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, &region_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, &region_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, &region_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;

View File

@ -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;

View File

@ -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 */

View File

@ -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);