Fix T94071: Area Split Improvements

Allow area Split to be initiated in any area and give better feedback
when not allowed.

See D13599 for more details and usage examples.

Differential Revision: https://developer.blender.org/D13599

Reviewed by Campbell Barton
This commit is contained in:
Harley Acheson 2022-01-12 09:41:46 -08:00
parent a0dcd0bf2c
commit fa8c2c7885
Notes: blender-bot 2023-05-22 12:40:41 +02:00
Referenced by issue #94071, Making a Horizontal Split from the top menu bar is buggy
1 changed files with 34 additions and 17 deletions

View File

@ -2083,15 +2083,31 @@ typedef struct sAreaSplitData {
} sAreaSplitData;
static bool area_split_allowed(const ScrArea *area, const eScreenAxis dir_axis)
{
if (!area || area->global) {
/* Must be a non-global area. */
return false;
}
if ((dir_axis == SCREEN_AXIS_V && area->winx <= 2 * AREAMINX) ||
(dir_axis == SCREEN_AXIS_H && area->winy <= 2 * ED_area_headersize())) {
/* Must be at least double minimum sizes to split into two. */
return false;
}
return true;
}
static void area_split_draw_cb(const struct wmWindow *UNUSED(win), void *userdata)
{
const wmOperator *op = userdata;
sAreaSplitData *sd = op->customdata;
if (sd->sarea) {
const eScreenAxis dir_axis = RNA_enum_get(op->ptr, "direction");
float fac = RNA_float_get(op->ptr, "factor");
const eScreenAxis dir_axis = RNA_enum_get(op->ptr, "direction");
if (area_split_allowed(sd->sarea, dir_axis)) {
float fac = RNA_float_get(op->ptr, "factor");
screen_draw_split_preview(sd->sarea, dir_axis, fac);
}
}
@ -2121,18 +2137,6 @@ static bool area_split_init(bContext *C, wmOperator *op)
/* required properties */
const eScreenAxis dir_axis = RNA_enum_get(op->ptr, "direction");
/* minimal size */
if (dir_axis == SCREEN_AXIS_V) {
if (area->winx < 2 * AREAMINX) {
return false;
}
}
else {
if (area->winy < 2 * ED_area_headersize()) {
return false;
}
}
/* custom data */
sAreaSplitData *sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split");
op->customdata = sd;
@ -2189,6 +2193,10 @@ static bool area_split_apply(bContext *C, wmOperator *op)
float fac = RNA_float_get(op->ptr, "factor");
const eScreenAxis dir_axis = RNA_enum_get(op->ptr, "direction");
if (!area_split_allowed(sd->sarea, dir_axis)) {
return false;
}
sd->narea = area_split(win, screen, sd->sarea, dir_axis, fac, false); /* false = no merge */
if (sd->narea == NULL) {
@ -2254,9 +2262,15 @@ static void area_split_exit(bContext *C, wmOperator *op)
static void area_split_preview_update_cursor(bContext *C, wmOperator *op)
{
wmWindow *win = CTX_wm_window(C);
sAreaSplitData *sd = (sAreaSplitData *)op->customdata;
const eScreenAxis dir_axis = RNA_enum_get(op->ptr, "direction");
WM_cursor_set(win, (dir_axis == SCREEN_AXIS_H) ? WM_CURSOR_H_SPLIT : WM_CURSOR_V_SPLIT);
if (area_split_allowed(sd->sarea, dir_axis)) {
WM_cursor_set(CTX_wm_window(C),
(dir_axis == SCREEN_AXIS_H) ? WM_CURSOR_H_SPLIT : WM_CURSOR_V_SPLIT);
}
else {
WM_cursor_set(CTX_wm_window(C), WM_CURSOR_STOP);
}
}
/* UI callback, adds new handler */
@ -2509,6 +2523,9 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (sd->sarea) {
ED_area_tag_redraw(sd->sarea);
}
area_split_preview_update_cursor(C, op);
/* area context not set */
sd->sarea = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, event->xy);