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;
JulianEisel marked this conversation as resolved Outdated
  /** 
   * 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.
   */
``` /** * 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. */
@ -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 */
JulianEisel marked this conversation as resolved Outdated

As this function runs a lot I think it would be best to take screen variables directly, e.g. (wm, area, region) arguments and not set the context.


To expand on this, in tests with some basic interaction the region_poll function runs ~19 times on frame change with the default scene, the same on mouse wheel and mouse motion with some modal operators.
Testing some basic interactivity - this function can run 10's of thousands of times in a minute or so
While I don't see this as a problem for simple checks - passing in the necessary arguments ensures slower lookups aren't used. It's also in keeping with other callbacks which take windowing arguments.

Even in this patch the function calls for data-access aren't as directly as they might be: CTX_wm_space_clip(C) calls into CTX_wm_area(..) -> ctx_wm_python_context_get(..), then CTX_py_dict_get(C) & BLI_thread_is_main().

If you anticipate needing access to data besides the area/region in the future, a parameters struct could be used instead of multiple arguments - so the scene or window can be added without having to update the function signature for every poll() function.

As this function runs a _lot_ I think it would be best to take screen variables directly, e.g. `(wm, area, region)` arguments and not set the context. ---- To expand on this, in tests with some basic interaction the `region_poll` function runs ~19 times on frame change with the default scene, the same on mouse wheel and mouse motion with some modal operators. Testing some basic interactivity - this function can run 10's of thousands of times in a minute or so While I don't see this as a problem for simple checks - passing in the necessary arguments ensures slower lookups aren't used. It's also in keeping with other callbacks which take windowing arguments. Even in this patch the function calls for data-access aren't as directly as they might be: `CTX_wm_space_clip(C)` calls into `CTX_wm_area(..)` -> `ctx_wm_python_context_get(..)`, then `CTX_py_dict_get(C)` & `BLI_thread_is_main()`. If you anticipate needing access to data besides the area/region in the future, a parameters struct could be used instead of multiple arguments - so the scene or window can be added without having to update the function signature for every poll() function.
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);
JulianEisel marked this conversation as resolved Outdated

MEM_callocN -> MEM_cnew

`MEM_callocN` -> `MEM_cnew`
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);