[Bf-blender-cvs] [91d0f6f] gooseberry: Modifier Drag&Drop

Julian Eisel noreply at git.blender.org
Fri Mar 6 17:24:53 CET 2015


Commit: 91d0f6f1139054abcfca3d8044eae6e2bb82fb9a
Author: Julian Eisel
Date:   Fri Mar 6 17:21:34 2015 +0100
Branches: gooseberry
https://developer.blender.org/rB91d0f6f1139054abcfca3d8044eae6e2bb82fb9a

Modifier Drag&Drop

**Warning: WIP!** Basic functionality works fine and there shouldn't be any crashes, however, if you occur issues, feel free to report them to me (not in the bug tracker!)

Some more effort is needed to get this ready for master, but I thought it would be nice as a little present for the Gooseberry-team (I heard some of you were requesting this?) and the ones using the Gooseberry-builds :)

Oh, and better not look at that code, it's ugly and a lot of changes are planned, I just wanted to get something working before getting into details.

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

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_layout.c
M	source/blender/editors/interface/interface_panel.c
M	source/blender/editors/interface/interface_templates.c
M	source/blender/editors/interface/interface_utils.c
M	source/blender/editors/interface/interface_widgets.c
M	source/blender/editors/mesh/editmesh_select.c
M	source/blender/makesrna/intern/rna_ui_api.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index f530a05..9c9c42b 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -40,10 +40,12 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         layout.operator_menu_enum("object.modifier_add", "type")
 
         for md in ob.modifiers:
+            layout.subblock_begin(md.name)
             box = layout.template_modifier(md)
             if box:
                 # match enum type to our functions, avoids a lookup table.
                 getattr(self, md.type)(box, ob, md)
+            layout.subblock_end()
 
     # the mt.type enum is (ab)used for a lookup on function names
     # ...to avoid lengthy if statements
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 154554a..3716fe7 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -144,6 +144,7 @@ enum {
 
 #define UI_BLOCK_LIST_ITEM   (1 << 19)
 #define UI_BLOCK_RADIAL      (1 << 20)
+#define UI_BLOCK_DRAGGABLE   (1 << 21)
 
 /* uiPopupBlockHandle->menuretval */
 #define UI_RETURN_CANCEL     (1 << 0)   /* cancel all menus cascading */
@@ -823,6 +824,8 @@ enum {
 uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, struct uiStyle *style);
 void UI_block_layout_set_current(uiBlock *block, uiLayout *layout);
 void UI_block_layout_resolve(uiBlock *block, int *x, int *y);
+void uiLayoutSubblockBegin(uiLayout *layout, const char *identifier);
+void uiLayoutSubblockEnd(uiLayout *layout);
 
 uiBlock *uiLayoutGetBlock(uiLayout *layout);
 
@@ -1023,6 +1026,9 @@ void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p);
 bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src);
 void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p);
 
+/* UI_subblock_ helplers */
+bool UI_subblock_is_dragging(uiBlock *block);
+
 
 /* Float precision helpers */
 #define UI_PRECISION_FLOAT_MAX 7
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index bad09a7..2056269 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1188,6 +1188,16 @@ void UI_block_update_from_old(const bContext *C, uiBlock *block)
 	block->auto_open_last = block->oldblock->auto_open_last;
 	block->tooltipdisabled = block->oldblock->tooltipdisabled;
 	BLI_movelisttolist(&block->color_pickers.list, &block->oldblock->color_pickers.list);
+	/* sub-block drag & drop data */
+	if (UI_subblock_is_dragging(block->oldblock)) {
+		block->subblock.drag_state = block->oldblock->subblock.drag_state;
+		block->subblock.rect = block->oldblock->subblock.rect;
+		block->subblock.rect_above = block->oldblock->subblock.rect_above;
+		block->subblock.rect_below = block->oldblock->subblock.rect_below;
+		copy_v2_v2_int(block->subblock.click_xy, block->oldblock->subblock.click_xy);
+		copy_v2_v2_int(block->subblock.drag_xy_prev, block->oldblock->subblock.drag_xy_prev);
+		BLI_strncpy(block->subblock.dragged_subblock, block->oldblock->subblock.dragged_subblock, MAX_NAME);
+	}
 
 	block->oldblock = NULL;
 }
@@ -1319,10 +1329,25 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u
 	rect->ymax = floorf(rectf.ymax);
 }
 
+static void ui_but_draw(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rcti *rect)
+{
+	/* XXX: figure out why invalid coordinates happen when closing render window */
+	/* and material preview is redrawn in main window (temp fix for bug #23848) */
+	if (rect->xmin < rect->xmax && rect->ymin < rect->ymax)
+		ui_draw_but(C, ar, style, but, rect);
+}
+
+static bool ui_subblock_is_but_dragged(uiBlock *block, uiBut *but)
+{
+	return (but->subblock_id[0] && STREQ(but->subblock_id, block->subblock.dragged_subblock));
+}
+
+#include "BIF_glutil.h"
 /* uses local copy of style, to scale things down, and allow widgets to change stuff */
 void UI_block_draw(const bContext *C, uiBlock *block)
 {
 	uiStyle style = *UI_style_get_dpi();  /* XXX pass on as arg */
+	wmWindow *win = CTX_wm_window(C);
 	ARegion *ar;
 	uiBut *but;
 	rcti rect;
@@ -1370,17 +1395,59 @@ void UI_block_draw(const bContext *C, uiBlock *block)
 	else if (block->panel)
 		ui_draw_aligned_panel(&style, block, &rect, UI_panel_category_is_visible(ar));
 
-	/* widgets */
+	/********** widgets **********/
+
+	/* first pass: draw not-dragged widgets */
 	for (but = block->buttons.first; but; but = but->next) {
 		if (!(but->flag & (UI_HIDDEN | UI_SCROLLED))) {
 			ui_but_to_pixelrect(&rect, ar, block, but);
-		
-			/* XXX: figure out why invalid coordinates happen when closing render window */
-			/* and material preview is redrawn in main window (temp fix for bug #23848) */
-			if (rect.xmin < rect.xmax && rect.ymin < rect.ymax)
-				ui_draw_but(C, ar, &style, but, &rect);
+
+			if (UI_subblock_is_dragging(block)) {
+				if (ui_subblock_is_but_dragged(block, but)) {
+					continue;
+				}
+			}
+
+			ui_but_draw(C, ar, &style, but, &rect);
+		}
+	}
+
+	/* second pass: draw dragged widgets above others */
+	if (UI_subblock_is_dragging(block)) {
+		int mx = win->eventstate->x, my = win->eventstate->y;
+		int drag_ofs_y = my - block->subblock.drag_xy_prev[1];
+		int ofs = 0;
+
+		ui_window_to_block(ar, block, &mx, &my);
+		ofs = block->subblock.click_xy[1] - (my - (block->subblock.rect.ymin + drag_ofs_y));
+
+		for (but = block->buttons.first; but; but = but->next) {
+			if (ui_subblock_is_but_dragged(block, but) &&
+			    !(but->flag & (UI_HIDDEN | UI_SCROLLED)))
+			{
+				ui_but_to_pixelrect(&rect, ar, block, but);
+				BLI_rcti_translate(&rect, 0, drag_ofs_y - ofs);
+
+				ui_but_draw(C, ar, &style, but, &rect);
+			}
 		}
+		BLI_rctf_translate(&block->subblock.rect, 0, drag_ofs_y - ofs);
+	}
+
+#if 0 /* debugging - draw border around sub-blocks */
+	if (UI_subblock_is_dragging(block)) {
+		rctf rectf = block->subblock.rect;
+		
+		ui_block_to_window_rctf(ar, block, &rectf, &block->subblock.rect);
+		
+		rectf.xmin -= ar->winrct.xmin;
+		rectf.ymin -= ar->winrct.ymin;
+		rectf.xmax -= ar->winrct.xmin;
+		rectf.ymax -= ar->winrct.ymin;
+
+		fdrawbox(rectf.xmin, rectf.ymin, rectf.xmax, rectf.ymax);
 	}
+#endif
 	
 	/* restore matrix */
 	glMatrixMode(GL_PROJECTION);
@@ -2541,6 +2608,10 @@ void UI_block_region_set(uiBlock *block, ARegion *region)
 			oldblock->active = 0;
 			oldblock->panel = NULL;
 			oldblock->handle = NULL;
+
+			if (UI_subblock_is_dragging(oldblock)) {
+				block->rect = oldblock->rect;
+			}
 		}
 
 		/* at the beginning of the list! for dynamical menus/blocks */
@@ -3122,6 +3193,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
 	
 	but->pos = -1;   /* cursor invisible */
 
+	if (block->subblock.is_subblock_building) {
+		BLI_strncpy(but->subblock_id, block->subblock.subblock_id[block->subblock.tot_subblocks], MAX_NAME);
+	}
+
 	if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {    /* add a space to name */
 		/* slen remains unchanged from previous assignment, ensure this stays true */
 		if (slen > 0 && slen < UI_MAX_NAME_STR - 2) {
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 9697319..6179ab1 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -110,6 +110,9 @@
 /* This hack is needed because we don't have a good way to re-reference keymap items once added: T42944 */
 #define USE_KEYMAP_ADD_HACK
 
+static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(userdata));
+static void ui_region_handler_remove(bContext *C, void *UNUSED(userdata));
+
 /* proto */
 static void ui_but_smart_controller_add(bContext *C, uiBut *from, uiBut *to);
 static void ui_but_link_add(bContext *C, uiBut *from, uiBut *to);
@@ -7901,6 +7904,160 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
 	return retval;
 }
 
+static rctf UI_subblock_boundbox_set(uiBlock *block, const char *subblock_id)
+{
+	uiBut *but;
+	rctf rect;
+
+	if (subblock_id && subblock_id[0]) {
+		for (but = block->buttons.first; but; but = but->next) {
+			if (but->subblock_id[0] && STREQ(but->subblock_id, subblock_id)) {
+				if (BLI_rctf_is_empty(&rect)) {
+					rect = but->rect;
+				}
+				BLI_rctf_union(&rect, &but->rect);
+			}
+		}
+	}
+	else {
+		/* return empty rect */
+		rect.xmin = rect.xmax = rect.ymin = rect.ymax = 0;
+	}
+	return rect;
+}
+
+static char *UI_subblock_get_prev_id(uiBlock *block, const char *subblock_id)
+{
+	int i;
+
+	for (i = 1; i < block->subblock.tot_subblocks; i++) {
+		if (STREQ(block->subblock.subblock_id[i], subblock_id)) {
+			if (block->subblock.subblock_id[i - 1] && block->subblock.subblock_id[i - 1][0]) {
+				return block->subblock.subblock_id[i - 1];
+			}
+		}
+	}
+	return NULL;
+}
+
+static char *UI_subblock_get_next_id(uiBlock *block, const char *subblock_id)
+{
+	int i;
+
+	for (i = 0; i < block->subblock.tot_subblocks; i++) {
+		if (STREQ(block->subblock.subblock_id[i], subblock_id)) {
+			if (block->subblock.subblock_id[i + 1] && block->subblock.subblock_id[i + 1][0]) {
+				return block->subblock.subblock_id[i + 1];
+			}
+		}
+	}
+	return NULL;
+}
+
+static void UI_subblock_neighbours_rects_set(uiBlock *block, const char *subblock_id)
+{
+	block->subblock.rect_above = UI_subblock_boundbox_set(block, UI_subblock_get_prev_id(block, subblock_id));
+	block->subblock.rect_below = UI_subblock_boundbox_set(block, UI_subblock_get_next_id(block, subblock_id));
+}
+
+static int ui_subblock_handler(bContext *C, const wmEvent *event, void *userdata)
+{
+	uiBut *but = (uiBut *)userdata;
+	uiBlock *block = but->block;
+
+	if (UI_subblock_is_dragging(block) == false)
+		return WM_UI_HANDLER_CONTINUE;
+
+	if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+		wmWindow *win = CTX_wm_window(C);
+		ARegion *ar = CTX_wm_region(C);
+
+		block->subb

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list