Page MenuHome
Paste P1073

(An Untitled Masterwork)
ActivePublic

Authored by Brecht Van Lommel (brecht) on Aug 21 2019, 2:29 AM.
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index eccd85ab276..3eceef45ef9 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -1132,6 +1132,52 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Area edge detection utility
+ * \{ */
+
+static ScrEdge *screen_area_edge_from_cursor(const bContext *C,
+ const int cursor[2],
+ ScrArea **r_sa1,
+ ScrArea **r_sa2)
+{
+ wmWindow *win = CTX_wm_window(C);
+ bScreen *sc = CTX_wm_screen(C);
+ ScrEdge *actedge;
+ rcti window_rect;
+
+ WM_window_rect_calc(win, &window_rect);
+ actedge = screen_geom_area_map_find_active_scredge(
+ AREAMAP_FROM_SCREEN(sc), &window_rect, cursor[0], cursor[1]);
+
+ *r_sa1 = NULL;
+ *r_sa2 = NULL;
+ if (actedge == NULL) {
+ return NULL;
+ }
+
+ int borderwidth = (4 * UI_DPI_FAC);
+ ScrArea *sa1, *sa2;
+ if (screen_geom_edge_is_horizontal(actedge)) {
+ sa1 = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, cursor[0], cursor[1] + borderwidth);
+ sa2 = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, cursor[0], cursor[1] - borderwidth);
+ }
+ else {
+ sa1 = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, cursor[0] + borderwidth, cursor[1]);
+ sa2 = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, cursor[0] - borderwidth, cursor[1]);
+ }
+
+ bool isGlobal = ((sa1 && ED_area_is_global(sa1)) || (sa2 && ED_area_is_global(sa2)));
+ if (!isGlobal && area_getorientation(sa1, sa2) != -1) {
+ *r_sa1 = sa1;
+ *r_sa2 = sa2;
+ }
+
+ return actedge;
+}
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Swap Area Operator
* \{ */
@@ -1151,6 +1197,7 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot)
* callbacks:
*
* invoke() gets called on shift+lmb drag in action-zone
+ * exec() execute without any user interaction, based on properties
* call init(), add handler
*
* modal() accept modal events while doing it
@@ -1241,6 +1288,23 @@ static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+static int area_swap_exec(bContext *C, wmOperator *op)
+{
+ ScrArea *sa1, *sa2;
+ int cursor[2];
+
+ RNA_int_get_array(op->ptr, "cursor", cursor);
+ screen_area_edge_from_cursor(C, cursor, &sa1, &sa2);
+
+ if (sa1 == NULL || sa2 == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ ED_area_swapspace(C, sa1, sa2);
+
+ return OPERATOR_FINISHED;
+}
+
static void SCREEN_OT_area_swap(wmOperatorType *ot)
{
ot->name = "Swap Areas";
@@ -1249,10 +1313,15 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
ot->invoke = area_swap_invoke;
ot->modal = area_swap_modal;
- ot->poll = ED_operator_areaactive;
+ ot->exec = area_swap_exec;
+ ot->poll = screen_active_editable;
ot->cancel = area_swap_cancel;
ot->flag = OPTYPE_BLOCKING;
+
+ /* rna */
+ RNA_def_int_vector(
+ ot->srna, "cursor", 2, NULL, INT_MIN, INT_MAX, "Cursor", "", INT_MIN, INT_MAX);
}
/** \} */
@@ -3175,40 +3244,20 @@ static void area_join_draw_cb(const struct wmWindow *UNUSED(win), void *userdata
/* validate selection inside screen, set variables OK */
/* return 0: init failed */
-/* XXX todo: find edge based on (x,y) and set other area? */
-static int area_join_init(bContext *C, wmOperator *op)
+static int area_join_init(bContext *C, wmOperator *op, ScrArea *sa1, ScrArea *sa2)
{
- const wmWindow *win = CTX_wm_window(C);
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *sa1, *sa2;
- sAreaJoinData *jd = NULL;
- int x1, y1;
- int x2, y2;
-
- /* required properties, make negative to get return 0 if not set by caller */
- x1 = RNA_int_get(op->ptr, "min_x");
- y1 = RNA_int_get(op->ptr, "min_y");
- x2 = RNA_int_get(op->ptr, "max_x");
- y2 = RNA_int_get(op->ptr, "max_y");
-
- sa1 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, x1, y1);
- if (sa1 == NULL) {
- sa1 = BKE_screen_area_map_find_area_xy(&win->global_areas, SPACE_TYPE_ANY, x1, y1);
- }
- sa2 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, x2, y2);
- if (sa2 == NULL) {
- sa2 = BKE_screen_area_map_find_area_xy(&win->global_areas, SPACE_TYPE_ANY, x2, y2);
- }
- if ((sa1 && ED_area_is_global(sa1)) || (sa2 && ED_area_is_global(sa2))) {
- BKE_report(
- op->reports, RPT_ERROR, "Global areas (Top Bar, Status Bar) do not support joining");
- return 0;
+ if (sa1 == NULL || sa2 == NULL) {
+ /* Get areas from cursor location if not specified. */
+ int cursor[2];
+ RNA_int_get_array(op->ptr, "cursor", cursor);
+ screen_area_edge_from_cursor(C, cursor, &sa1, &sa2);
}
- else if (sa1 == NULL || sa2 == NULL || sa1 == sa2) {
+
+ if (sa1 == NULL || sa2 == NULL) {
return 0;
}
- jd = (sAreaJoinData *)MEM_callocN(sizeof(sAreaJoinData), "op_area_join");
+ sAreaJoinData *jd = MEM_callocN(sizeof(sAreaJoinData), "op_area_join");
jd->sa1 = sa1;
jd->sa2 = sa2;
@@ -3261,7 +3310,7 @@ static void area_join_exit(bContext *C, wmOperator *op)
static int area_join_exec(bContext *C, wmOperator *op)
{
- if (!area_join_init(C, op)) {
+ if (!area_join_init(C, op, NULL, NULL)) {
return OPERATOR_CANCELLED;
}
@@ -3292,15 +3341,14 @@ static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_PASS_THROUGH;
}
- /* prepare operator state vars */
- RNA_int_set(op->ptr, "min_x", sad->sa1->totrct.xmin);
- RNA_int_set(op->ptr, "min_y", sad->sa1->totrct.ymin);
- RNA_int_set(op->ptr, "max_x", sad->sa2->totrct.xmin);
- RNA_int_set(op->ptr, "max_y", sad->sa2->totrct.ymin);
+ if (!area_join_init(C, op, sad->sa1, sad->sa2)) {
+ return OPERATOR_CANCELLED;
+ }
}
-
- if (!area_join_init(C, op)) {
- return OPERATOR_CANCELLED;
+ else {
+ if (!area_join_init(C, op, NULL, NULL)) {
+ return OPERATOR_CANCELLED;
+ }
}
/* add temp handler */
@@ -3431,10 +3479,8 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
/* rna */
- RNA_def_int(ot->srna, "min_x", -100, INT_MIN, INT_MAX, "X 1", "", INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "min_y", -100, INT_MIN, INT_MAX, "Y 1", "", INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "max_x", -100, INT_MIN, INT_MAX, "X 2", "", INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "max_y", -100, INT_MIN, INT_MAX, "Y 2", "", INT_MIN, INT_MAX);
+ RNA_def_int_vector(
+ ot->srna, "cursor", 2, NULL, INT_MIN, INT_MAX, "Cursor", "", INT_MIN, INT_MAX);
}
/** \} */
@@ -3445,36 +3491,73 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- const wmWindow *win = CTX_wm_window(C);
- const bScreen *sc = CTX_wm_screen(C);
uiPopupMenu *pup;
uiLayout *layout;
PointerRNA ptr;
- ScrEdge *actedge;
- rcti window_rect;
-
- WM_window_rect_calc(win, &window_rect);
- actedge = screen_geom_area_map_find_active_scredge(
- AREAMAP_FROM_SCREEN(sc), &window_rect, event->x, event->y);
+ ScrArea *sa1, *sa2;
- if (actedge == NULL) {
+ if (screen_area_edge_from_cursor(C, &event->x, &sa1, &sa2) == NULL) {
return OPERATOR_CANCELLED;
}
pup = UI_popup_menu_begin(C, WM_operatortype_name(op->type, op->ptr), ICON_NONE);
layout = UI_popup_menu_layout(pup);
- uiItemFullO(
- layout, "SCREEN_OT_area_split", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr);
+ /* Vertical Split */
+ uiItemFullO(layout,
+ "SCREEN_OT_area_split",
+ IFACE_("Vertical Split"),
+ ICON_NONE,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &ptr);
+ /* store initial mouse cursor position */
+ RNA_int_set_array(&ptr, "cursor", &event->x);
+ RNA_enum_set(&ptr, "direction", 'v');
+
+ /* Horizontal Split */
+
+ uiItemFullO(layout,
+ "SCREEN_OT_area_split",
+ IFACE_("Horizontal Split"),
+ ICON_NONE,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &ptr);
/* store initial mouse cursor position */
RNA_int_set_array(&ptr, "cursor", &event->x);
+ RNA_enum_set(&ptr, "direction", 'h');
+
+ /* Test if we can do a merge or swap. */
+ if (sa1 && sa2) {
+ uiItemS(layout);
- uiItemFullO(layout, "SCREEN_OT_area_join", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr);
- /* mouse cursor on edge, '4' can fail on wide edges... */
- RNA_int_set(&ptr, "min_x", event->x + 4);
- RNA_int_set(&ptr, "min_y", event->y + 4);
- RNA_int_set(&ptr, "max_x", event->x - 4);
- RNA_int_set(&ptr, "max_y", event->y - 4);
+ /* Join Areas */
+
+ uiItemFullO(layout,
+ "SCREEN_OT_area_join",
+ IFACE_("Join Areas"),
+ ICON_NONE,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &ptr);
+ RNA_int_set_array(&ptr, "cursor", &event->x);
+
+ /* Merge Areas */
+
+ uiItemFullO(layout,
+ "SCREEN_OT_area_swap",
+ IFACE_("Swap Areas"),
+ ICON_NONE,
+ NULL,
+ WM_OP_EXEC_DEFAULT,
+ 0,
+ &ptr);
+ RNA_int_set_array(&ptr, "cursor", &event->x);
+ }
UI_popup_menu_end(C, pup);