[Bf-blender-cvs] [def5999] master: UI: support for dragging popups title area

Campbell Barton noreply at git.blender.org
Wed Apr 2 09:44:15 CEST 2014


Commit: def5999f9b04368aa21485b514c0931f6fb43d8e
Author: Campbell Barton
Date:   Wed Apr 2 18:42:08 2014 +1100
https://developer.blender.org/rBdef5999f9b04368aa21485b514c0931f6fb43d8e

UI: support for dragging popups title area

===================================================================

M	source/blender/editors/include/ED_screen.h
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/screen/area.c
M	source/blender/windowmanager/intern/wm_subwindow.c
M	source/blender/windowmanager/wm_subwindow.h

===================================================================

diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 5e20734..1d1777a 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -55,6 +55,7 @@ void    ED_region_do_draw(struct bContext *C, struct ARegion *ar);
 void    ED_region_exit(struct bContext *C, struct ARegion *ar);
 void    ED_region_pixelspace(struct ARegion *ar);
 void    ED_region_set(const struct bContext *C, struct ARegion *ar);
+void    ED_region_update_rect(struct bContext *C, struct ARegion *ar);
 void    ED_region_init(struct bContext *C, struct ARegion *ar);
 void    ED_region_tag_redraw(struct ARegion *ar);
 void    ED_region_tag_redraw_partial(struct ARegion *ar, struct rcti *rct);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 5a520a6..e7c9900 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -96,6 +96,9 @@
 /* so we can avoid very small mouse-moves from jumping away from keyboard navigation [#34936] */
 #define USE_KEYNAV_LIMIT
 
+/* drag popups by their header */
+#define USE_DRAG_POPUP
+
 /* proto */
 static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to);
 static void ui_add_link(bContext *C, uiBut *from, uiBut *to);
@@ -7862,13 +7865,14 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
 }
 
 static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
-                                int level, const bool is_parent_inside)
+                                int level, const bool is_parent_inside, const bool is_floating)
 {
 	ARegion *ar;
 	uiBlock *block;
 	uiBut *but, *bt;
 	int mx, my, retval;
 	bool inside;
+	bool inside_title;  /* check for title dragging */
 
 	ar = menu->region;
 	block = ar->uiblocks.first;
@@ -7881,10 +7885,35 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
 
 	/* check if mouse is inside block */
 	inside = BLI_rctf_isect_pt(&block->rect, mx, my);
+	inside_title = inside && ((my + (UI_UNIT_Y * 1.5f)) > block->rect.xmax);
 
 	/* if there's an active modal button, don't check events or outside, except for search menu */
 	but = ui_but_find_activated(ar);
 
+#ifdef USE_DRAG_POPUP
+	if (menu->is_grab) {
+		if (event->type == LEFTMOUSE) {
+			menu->is_grab = false;
+		}
+		else {
+			if (event->type == MOUSEMOVE) {
+				int mdiff[2];
+
+				sub_v2_v2v2_int(mdiff, &event->x, menu->grab_xy_prev);
+				copy_v2_v2_int(menu->grab_xy_prev, &event->x);
+
+				BLI_rcti_translate(&ar->winrct, UNPACK2(mdiff));
+
+				ED_region_update_rect(C, ar);
+
+				ED_region_tag_redraw(ar);
+			}
+
+			return retval;
+		}
+	}
+#endif
+
 	if (but && button_modal_state(but->active->state)) {
 		if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) {
 			/* if a button is activated modal, always reset the start mouse
@@ -8220,6 +8249,16 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
 				if (!ui_but_find_activated(ar))
 					menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK;
 			}
+#ifdef USE_DRAG_POPUP
+			else if ((event->type == LEFTMOUSE) && (event->val == KM_PRESS) &&
+			         (inside && is_floating && inside_title))
+			{
+				if (!ui_but_find_activated(ar)) {
+					menu->is_grab = true;
+					copy_v2_v2_int(menu->grab_xy_prev, &event->x);
+				}
+			}
+#endif
 			else {
 
 				/* check mouse moving outside of the menu */
@@ -8328,7 +8367,7 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo
 }
 
 static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
-                                     int level, const bool is_parent_inside)
+                                     int level, const bool is_parent_inside, const bool is_floating)
 {
 	uiBut *but;
 	uiHandleButtonData *data;
@@ -8354,7 +8393,7 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
 			inside = BLI_rctf_isect_pt(&block->rect, mx, my);
 		}
 
-		retval = ui_handle_menus_recursive(C, event, submenu, level + 1, is_parent_inside || inside);
+		retval = ui_handle_menus_recursive(C, event, submenu, level + 1, is_parent_inside || inside, false);
 	}
 
 	/* now handle events for our own menu */
@@ -8387,7 +8426,7 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
 			}
 		}
 		else {
-			retval = ui_handle_menu_event(C, event, menu, level, is_parent_inside);
+			retval = ui_handle_menu_event(C, event, menu, level, is_parent_inside, is_floating);
 		}
 	}
 
@@ -8484,7 +8523,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
 			/* handle events for menus and their buttons recursively,
 			 * this will handle events from the top to the bottom menu */
 			if (data->menu)
-				retval = ui_handle_menus_recursive(C, event, data->menu, 0, false);
+				retval = ui_handle_menus_recursive(C, event, data->menu, 0, false, false);
 
 			/* handle events for the activated button */
 			if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) ||
@@ -8530,7 +8569,7 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
 		retval = WM_UI_HANDLER_CONTINUE;
 	}
 
-	ui_handle_menus_recursive(C, event, menu, 0, false);
+	ui_handle_menus_recursive(C, event, menu, 0, false, true);
 
 	/* free if done, does not free handle itself */
 	if (menu->menuretval) {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 2c6486b..bb32135 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -460,6 +460,11 @@ struct uiPopupBlockHandle {
 
 	/* menu direction */
 	int direction;
+
+/* #ifdef USE_DRAG_POPUP */
+	bool is_grab;
+	int     grab_xy_prev[2];
+/* #endif */
 };
 
 uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, void *arg_but);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index f62166d..1efd3cc 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -408,7 +408,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
 	/* see BKE_spacedata_draw_locks() */
 	if (at->do_lock)
 		return;
-	
+
 	/* if no partial draw rect set, full rect */
 	if (ar->drawrct.xmin == ar->drawrct.xmax) {
 		ar->drawrct = ar->winrct;
@@ -1312,6 +1312,27 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
 	}
 }
 
+static void region_update_rect(ARegion *ar)
+{
+	ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
+	ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
+
+	/* v2d mask is used to subtract scrollbars from a 2d view. Needs initialize here. */
+	BLI_rcti_init(&ar->v2d.mask, 0, ar->winx - 1, 0, ar->winy -1);
+}
+
+/**
+ * Call to move a popup window (keep OpenGL context free!)
+ */
+void ED_region_update_rect(bContext *C, ARegion *ar)
+{
+	wmWindow *win = CTX_wm_window(C);
+
+	wm_subwindow_rect_set(win, ar->swinid, &ar->winrct);
+
+	region_update_rect(ar);
+}
+
 /* externally called for floating regions like menus */
 void ED_region_init(bContext *C, ARegion *ar)
 {
@@ -1320,11 +1341,7 @@ void ED_region_init(bContext *C, ARegion *ar)
 	/* refresh can be called before window opened */
 	region_subwindow(CTX_wm_window(C), ar);
 	
-	ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
-	ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
-	
-	/* v2d mask is used to subtract scrollbars from a 2d view. Needs initialize here. */
-	BLI_rcti_init(&ar->v2d.mask, 0, ar->winx - 1, 0, ar->winy -1);
+	region_update_rect(ar);
 
 	/* UI convention */
 	wmOrtho2(-0.01f, ar->winx - 0.01f, -0.01f, ar->winy - 0.01f);
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 1c20fe3..ecf22fe 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -180,6 +180,20 @@ void wm_subwindow_rect_get(wmWindow *win, int swinid, rcti *r_rect)
 }
 
 
+static void wm_swin_rect_set(wmSubWindow *swin, const rcti *rect)
+{
+	swin->winrct = *rect;
+}
+void wm_subwindow_rect_set(wmWindow *win, int swinid, const rcti *rect)
+{
+	wmSubWindow *swin = swin_from_swinid(win, swinid);
+
+	if (swin) {
+		wm_swin_rect_set(swin, rect);
+	}
+}
+
+
 /* always sets pixel-precise 2D window/view matrices */
 /* coords is in whole pixels. xmin = 15, xmax = 16: means window is 2 pix big */
 int wm_subwindow_open(wmWindow *win, const rcti *winrct)
diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h
index c1d0f9a..bf7b994 100644
--- a/source/blender/windowmanager/wm_subwindow.h
+++ b/source/blender/windowmanager/wm_subwindow.h
@@ -46,6 +46,7 @@ void	wm_subwindow_size_get(wmWindow *win, int swinid, int *x, int *y);
 void	wm_subwindow_origin_get(wmWindow *win, int swinid, int *x, int *y);
 void	wm_subwindow_matrix_get(wmWindow *win, int swinid, float mat[4][4]);
 void	wm_subwindow_rect_get(wmWindow *win, int swinid, struct rcti *r_rect);
+void    wm_subwindow_rect_set(wmWindow *win, int swinid, const rcti *rect);
 
 unsigned int index_to_framebuffer(int index);




More information about the Bf-blender-cvs mailing list