Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarley Acheson <harley.acheson@gmail.com>2019-08-22 23:19:11 +0300
committerHarley Acheson <harley.acheson@gmail.com>2019-08-22 23:19:11 +0300
commit22ebc579872bb4c3d8e9428505058709f76db155 (patch)
tree1fc8b97db959872d79a0dcc3405bed3db2801cc1 /source/blender
parent7c3bbe93aaa293a27d9b88a0d4104e0b2661ef1a (diff)
UI: Changes to Area Options Menu
Adds more options to the context menu that pops up on area edges. Both Split types, Join, and Swap. Differential Revision: https://developer.blender.org/D5459 Reviewed by Brecht Van Lommel
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/screen/screen_ops.c199
1 files changed, 135 insertions, 64 deletions
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 7821540d045..9f0dc38750d 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -1118,7 +1118,44 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot)
RNA_def_int(ot->srna, "modifier", 0, 0, 2, "Modifier", "Modifier state", 0, 2);
}
-/** \} */
+/* -------------------------------------------------------------------- */
+/** \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) {
+ *r_sa1 = sa1;
+ *r_sa2 = sa2;
+ }
+ return actedge;
+}
/* -------------------------------------------------------------------- */
/** \name Swap Area Operator
@@ -1139,6 +1176,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
@@ -1229,6 +1267,19 @@ 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";
@@ -1237,10 +1288,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);
}
/** \} */
@@ -3180,40 +3236,19 @@ 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;
@@ -3266,7 +3301,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;
}
@@ -3296,16 +3331,11 @@ static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (sad->sa1 == sad->sa2) {
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)) {
- return OPERATOR_CANCELLED;
+ else {
+ if (!area_join_init(C, op, sad->sa1, sad->sa2)) {
+ return OPERATOR_CANCELLED;
+ }
+ }
}
/* add temp handler */
@@ -3326,7 +3356,12 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
bScreen *sc = CTX_wm_screen(C);
wmWindow *win = CTX_wm_window(C);
- sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
+ sAreaJoinData *jd;
+
+ if (op->customdata == NULL) {
+ area_join_init(C, op, NULL, NULL);
+ }
+ jd = (sAreaJoinData *)op->customdata;
/* execute the events */
switch (event->type) {
@@ -3436,10 +3471,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);
}
/** \} */
@@ -3450,36 +3483,74 @@ 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);
- /* store initial mouse cursor position */
+ /* 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');
- 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);
+ if (sa1 && sa2) {
+ uiItemS(layout);
+ }
+
+ /* Join needs two very similar areas. */
+ if (sa1 && sa2 && (area_getorientation(sa1, sa2) != -1)) {
+ 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);
+ }
+
+ /* Swap just needs two areas. */
+ if (sa1 && sa2) {
+ 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);