WIP: Area Editor Cycling #105161

Draft
Harley Acheson wants to merge 3 commits from Harley/blender:AreaCycle into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
2 changed files with 104 additions and 0 deletions

View File

@ -705,6 +705,10 @@ def km_window(params):
op_menu("SCREEN_MT_user_menu", {"type": 'Q', "value": 'PRESS'}),
# Fast editor switching
("screen.area_space_cycle", {"type": 'F1', "value": 'PRESS', "alt": True}, {"properties": [("direction", 'BACK')]}),
("screen.area_space_cycle", {"type": 'F2', "value": 'PRESS', "alt": True}, {"properties": [("direction", 'FORWARD')]}),
*(
("screen.space_type_set_or_cycle",
{"type": k, "value": 'PRESS', "shift": True},

View File

@ -5664,6 +5664,105 @@ static void SCREEN_OT_space_type_set_or_cycle(wmOperatorType *ot)
RNA_def_enum(ot->srna, "space_type", rna_enum_space_type_items, SPACE_EMPTY, "Type", "");
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Area Space Cycle
* \{ */
static const EnumPropertyItem area_space_cycle_direction[] = {
{0, "BACK", 0, "Back", ""},
{1, "FORWARD", 0, "Forward", ""},
{0, nullptr, 0, nullptr, nullptr},
};
static bool area_space_cycle_poll(bContext *C)
{
ScrArea *area = CTX_wm_area(C);
return (area && !ELEM(area->spacetype, SPACE_TOPBAR, SPACE_STATUSBAR) &&
BLI_listbase_count_at_most(&area->spacedata, 2) > 1);
}
static int area_space_cycle_exec(bContext *C, wmOperator *op)
{
const eScreenCycle direction = eScreenCycle(RNA_enum_get(op->ptr, "direction"));
ScrArea *area = CTX_wm_area(C);
wmWindow *win = CTX_wm_window(C);
SpaceLink *slold = static_cast<SpaceLink *>(area->spacedata.first);
SpaceLink *slnew;
/* XXX: No attempt to deal with header alignment. */
bool skip_region_exit = true;
void (*area_exit)(wmWindowManager *, ScrArea *) = area->type ? area->type->exit : nullptr;
if (skip_region_exit && area->type) {
area->type->exit = nullptr;
}
ED_area_exit(C, area);
if (skip_region_exit && area->type) {
area->type->exit = area_exit;
}
if (direction == SPACE_CONTEXT_CYCLE_PREV) {
BLI_remlink(&area->spacedata, slold);
BLI_addtail(&area->spacedata, slold);
slnew = static_cast<SpaceLink *>(area->spacedata.first);
}
else {
slnew = static_cast<SpaceLink *>(area->spacedata.last);
BLI_remlink(&area->spacedata, slnew);
BLI_addhead(&area->spacedata, slnew);
}
area->spacetype = slnew->spacetype;
/* swap regions */
slold->regionbase = area->regionbase;
area->regionbase = slnew->regionbase;
BLI_listbase_clear(&slnew->regionbase);
/* SPACE_FLAG_TYPE_WAS_ACTIVE is only used to go back to a previously active space that is
* overlapped by temporary ones. It's now properly activated, so the flag should be cleared
* at this point. */
slnew->link_flag &= ~SPACE_FLAG_TYPE_WAS_ACTIVE;
ED_area_init(CTX_wm_manager(C), win, area);
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(win);
/* send space change notifier */
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CHANGED, area);
ED_area_tag_refresh(area);
ED_area_tag_redraw(area);
return OPERATOR_FINISHED;
}
static void SCREEN_OT_area_space_cycle(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Cycle Area Editors";
ot->description = "Cycle through an area's editors";
ot->idname = "SCREEN_OT_area_space_cycle";
/* api callbacks */
ot->exec = area_space_cycle_exec;
ot->poll = area_space_cycle_poll;
ot->flag = 0;
RNA_def_enum(ot->srna,
"direction",
area_space_cycle_direction,
0,
"Direction",
"Direction to cycle through");
}
/** \} */
/* -------------------------------------------------------------------- */
@ -5861,6 +5960,7 @@ void ED_operatortypes_screen()
WM_operatortype_append(SCREEN_OT_space_type_set_or_cycle);
WM_operatortype_append(SCREEN_OT_space_context_cycle);
WM_operatortype_append(SCREEN_OT_workspace_cycle);
WM_operatortype_append(SCREEN_OT_area_space_cycle);
/* Frame changes. */
WM_operatortype_append(SCREEN_OT_frame_offset);