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
9 changed files with 183 additions and 301 deletions
Showing only changes of commit 2bbe699bc1 - Show all commits

View File

@ -166,7 +166,8 @@ typedef struct ARegionType {
void (*exit)(struct wmWindowManager *wm, struct ARegion *region);
/** Optional callback to decide whether the region should be treated as existing given the
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. */
* current context. When returning false, the region will be kept in storage, but is not
* available to the user in any way. */
* available to the user in any way. Callbacks can assume that context has the owning area and
* space-data set. */
bool (*poll)(const struct bContext *C);
/* draw entirely, view changes should be handled here */
void (*draw)(const struct bContext *C, struct ARegion *region);
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.

View File

@ -2078,6 +2078,66 @@ 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: {
ARegion *new_region;
new_region = do_versions_add_region_if_not_found(
JulianEisel marked this conversation as resolved Outdated

How about something like this?

  if (ARegion *new_region = do_versions_add_region_if_not_found(
          regionbase, RGN_TYPE_EXECUTE, "versioning: execute region for file", RGN_TYPE_UI)) {
    new_region->alignment = RGN_ALIGN_BOTTOM;
    new_region->flag = RGN_FLAG_DYNAMIC_SIZE;
  }
How about something like this? ```c++ if (ARegion *new_region = do_versions_add_region_if_not_found( regionbase, RGN_TYPE_EXECUTE, "versioning: execute region for file", RGN_TYPE_UI)) { new_region->alignment = RGN_ALIGN_BOTTOM; new_region->flag = RGN_FLAG_DYNAMIC_SIZE; } ```
regionbase, RGN_TYPE_UI, "versioning: UI region for file", RGN_TYPE_TOOLS);
if (new_region) {
new_region->alignment = RGN_ALIGN_TOP;
new_region->flag |= RGN_FLAG_DYNAMIC_SIZE;
}
new_region = do_versions_add_region_if_not_found(
regionbase, RGN_TYPE_EXECUTE, "versioning: execute region for file", RGN_TYPE_UI);
if (new_region) {
new_region->alignment = RGN_ALIGN_BOTTOM;
new_region->flag = RGN_FLAG_DYNAMIC_SIZE;
}
new_region = do_versions_add_region_if_not_found(regionbase,
RGN_TYPE_TOOL_PROPS,
"versioning: tool props region for file",
RGN_TYPE_EXECUTE);
if (new_region) {
new_region->alignment = RGN_ALIGN_RIGHT;
new_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;
}
}
}
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
{
@ -4020,37 +4080,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype != SPACE_FILE) {
continue;
}
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
&sl->regionbase;
ARegion *new_region;
if ((new_region = do_versions_add_region_if_not_found(
regionbase,
RGN_TYPE_UI,
"versioning: UI region for space file",
RGN_TYPE_TOOLS))) {
new_region->alignment = RGN_ALIGN_TOP;
new_region->flag |= RGN_FLAG_DYNAMIC_SIZE;
}
if ((new_region = do_versions_add_region_if_not_found(
regionbase,
RGN_TYPE_EXECUTE,
"versioning: execute region for space file",
RGN_TYPE_UI))) {
new_region->alignment = RGN_ALIGN_BOTTOM;
new_region->flag = RGN_FLAG_DYNAMIC_SIZE;
}
if ((new_region = do_versions_add_region_if_not_found(
regionbase,
RGN_TYPE_TOOL_PROPS,
"versioning: tool props region for space file",
RGN_TYPE_EXECUTE))) {
new_region->alignment = RGN_ALIGN_RIGHT;
new_region->flag = RGN_FLAG_HIDDEN;
}
version_ensure_missing_regions(area, sl);
}
}
}

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 = static_cast<ARegion *>(MEM_callocN(sizeof(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

@ -34,7 +34,6 @@ set(SRC
clip_graph_draw.c
clip_graph_ops.c
clip_ops.c
clip_toolbar.c
clip_utils.c
space_clip.c
tracking_ops.c

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.c */
struct ARegion *ED_clip_has_properties_region(struct ScrArea *area);
/* clip_utils.c */
typedef enum {

View File

@ -1,54 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2011 Blender Foundation. All rights reserved. */
/** \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 == NULL) {
return NULL;
}
arnew = MEM_callocN(sizeof(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 == NULL) {
return NULL;
}
arnew = MEM_callocN(sizeof(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 == NULL) {
return NULL;
}
arnew = MEM_callocN(sizeof(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;
@ -223,7 +147,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 *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceClip *sc;
@ -265,7 +189,7 @@ static SpaceLink *clip_create(const ScrArea *area, const Scene *scene)
region = MEM_callocN(sizeof(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_callocN(sizeof(ARegion), "main region for clip");
@ -621,99 +545,28 @@ static void clip_dropboxes(void)
WM_dropbox_add(lb, "CLIP_OT_open", clip_drop_poll, clip_drop_copy, NULL, NULL);
}
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);
@ -781,6 +634,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 bContext *C)
{
const SpaceClip *sclip = CTX_wm_space_clip(C);
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 bContext *C)
{
const SpaceClip *sclip = CTX_wm_space_clip(C);
return ELEM(sclip->view, SC_VIEW_GRAPH, SC_VIEW_DOPESHEET);
}
static void clip_preview_region_init(wmWindowManager *wm, ARegion *region)
{
wmKeyMap *keymap;
@ -1062,6 +927,12 @@ static void clip_preview_region_listener(const wmRegionListenerParams *UNUSED(pa
/****************** channels region ******************/
static bool clip_channels_region_poll(const bContext *C)
{
const SpaceClip *sclip = CTX_wm_space_clip(C);
return ELEM(sclip->view, SC_VIEW_DOPESHEET);
}
static void clip_channels_region_init(wmWindowManager *wm, ARegion *region)
{
wmKeyMap *keymap;
@ -1138,6 +1009,12 @@ static void clip_header_region_listener(const wmRegionListenerParams *params)
/****************** tools region ******************/
static bool clip_tools_region_poll(const bContext *C)
{
const SpaceClip *sclip = CTX_wm_space_clip(C);
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)
{
@ -1188,6 +1065,12 @@ static void clip_props_region_listener(const wmRegionListenerParams *params)
/****************** properties region ******************/
static bool clip_properties_region_poll(const bContext *C)
{
const SpaceClip *sclip = CTX_wm_space_clip(C);
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)
{
@ -1292,6 +1175,7 @@ void ED_spacetype_clip(void)
/* regions: main window */
art = MEM_callocN(sizeof(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;
@ -1303,6 +1187,7 @@ void ED_spacetype_clip(void)
art = MEM_callocN(sizeof(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;
@ -1315,6 +1200,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;
@ -1326,6 +1212,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;
@ -1351,6 +1238,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

@ -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;
@ -247,17 +246,6 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
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;
@ -268,17 +256,11 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
}
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;
@ -297,17 +279,10 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
/* 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;
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_main->alignment != RGN_ALIGN_NONE) {
@ -331,23 +306,12 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
ARegion *region_channels = sequencer_find_region(area, RGN_TYPE_CHANNELS);
if (sseq->view == SEQ_VIEW_SEQUENCE) {
if (region_channels && (region_channels->flag & RGN_FLAG_HIDDEN)) {
region_channels->flag &= ~RGN_FLAG_HIDDEN;
region_channels->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
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;
@ -508,6 +472,13 @@ static void sequencer_gizmos(void)
}
/* *********************** sequencer (main) region ************************ */
static bool sequencer_main_region_poll(const bContext *C)
{
const SpaceSeq *sseq = CTX_wm_space_seq(C);
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)
{
@ -761,6 +732,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 bContext *C)
{
const SpaceSeq *sseq = CTX_wm_space_seq(C);
return ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW);
}
static void sequencer_preview_region_init(wmWindowManager *wm, ARegion *region)
{
wmKeyMap *keymap;
@ -983,6 +961,12 @@ static void sequencer_id_remap(ScrArea *UNUSED(area),
/* ************************************* */
static bool sequencer_channel_region_poll(const bContext *C)
{
const SpaceSeq *sseq = CTX_wm_space_seq(C);
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)
{
@ -1070,6 +1054,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;
@ -1084,6 +1069,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;
@ -1122,6 +1108,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;