[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60018] branches/soc-2013-ui_replay/source /blender: Implemented drag and drop for the icon shelf.

Vincent Akkermans vincent at ack-err.net
Tue Sep 10 20:32:39 CEST 2013


Revision: 60018
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60018
Author:   ack-err
Date:     2013-09-10 18:32:38 +0000 (Tue, 10 Sep 2013)
Log Message:
-----------
Implemented drag and drop for the icon shelf. Removed code for menubar menus that was commented out.

Modified Paths:
--------------
    branches/soc-2013-ui_replay/source/blender/blenloader/intern/readfile.c
    branches/soc-2013-ui_replay/source/blender/blenloader/intern/writefile.c
    branches/soc-2013-ui_replay/source/blender/editors/include/UI_interface.h
    branches/soc-2013-ui_replay/source/blender/editors/interface/interface_handlers.c
    branches/soc-2013-ui_replay/source/blender/editors/interface/interface_intern.h
    branches/soc-2013-ui_replay/source/blender/editors/interface/interface_layout.c
    branches/soc-2013-ui_replay/source/blender/editors/interface/interface_panel.c
    branches/soc-2013-ui_replay/source/blender/editors/interface/interface_regions.c
    branches/soc-2013-ui_replay/source/blender/editors/screen/area.c
    branches/soc-2013-ui_replay/source/blender/makesdna/DNA_screen_types.h

Modified: branches/soc-2013-ui_replay/source/blender/blenloader/intern/readfile.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/blenloader/intern/readfile.c	2013-09-10 16:52:42 UTC (rev 60017)
+++ branches/soc-2013-ui_replay/source/blender/blenloader/intern/readfile.c	2013-09-10 18:32:38 UTC (rev 60018)
@@ -6181,6 +6181,7 @@
 	ar->swap = 0;
 	ar->do_draw = FALSE;
 	ar->regiontimer = NULL;
+	ar->dragdata = NULL;
 	memset(&ar->drawrct, 0, sizeof(ar->drawrct));
 }
 

Modified: branches/soc-2013-ui_replay/source/blender/blenloader/intern/writefile.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/blenloader/intern/writefile.c	2013-09-10 16:52:42 UTC (rev 60017)
+++ branches/soc-2013-ui_replay/source/blender/blenloader/intern/writefile.c	2013-09-10 18:32:38 UTC (rev 60018)
@@ -2387,7 +2387,7 @@
 }
 
 static void write_region(WriteData *wd, ARegion *ar, int spacetype)
-{	
+{
 	writestruct(wd, DATA, "ARegion", 1, ar);
 	
 	if (ar->regiondata) {

Modified: branches/soc-2013-ui_replay/source/blender/editors/include/UI_interface.h
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/include/UI_interface.h	2013-09-10 16:52:42 UTC (rev 60017)
+++ branches/soc-2013-ui_replay/source/blender/editors/include/UI_interface.h	2013-09-10 18:32:38 UTC (rev 60018)
@@ -44,6 +44,7 @@
 struct ListBase;
 struct ARegion;
 struct ARegionType;
+struct OperatorListItem;
 struct ScrArea;
 struct wmWindow;
 struct wmWindowManager;
@@ -79,6 +80,7 @@
 typedef struct uiBlock uiBlock;
 typedef struct uiPopupBlockHandle uiPopupBlockHandle;
 typedef struct uiLayout uiLayout;
+typedef struct uiHandleRegionDragData uiHandleRegionDragData;
 
 /* Defines */
 
@@ -905,7 +907,9 @@
 void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon);
 
 /* OperatorListItem utilities */
-int uiOperatorListItemPresent(ListBase *lb, const char *idname, IDProperty *properties);
+struct OperatorListItem *uiOperatorListItemPresent(ListBase *lb, const char *idname, IDProperty *properties);
+struct OperatorListItem *uiRegionDraggedOperatorListItem(struct ARegion *ar);
+int uiRegionDraggedNewIndex(struct ARegion *ar);
 
 
 /* UI Operators */

Modified: branches/soc-2013-ui_replay/source/blender/editors/interface/interface_handlers.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/interface/interface_handlers.c	2013-09-10 16:52:42 UTC (rev 60017)
+++ branches/soc-2013-ui_replay/source/blender/editors/interface/interface_handlers.c	2013-09-10 18:32:38 UTC (rev 60018)
@@ -7657,6 +7657,136 @@
 
 /* *************** UI event handlers **************** */
 
+static void ui_do_drag_button(const bContext *C, const wmEvent *event, ARegion *ar)
+{
+	uiHandleRegionDragData *data = ar->dragdata;
+	int cur_index = BLI_findindex(&ar->operators, data->oli);
+	int dx, dunits, maxindex;
+	
+	// Calculate the new index of the button based on the drag offset
+	dx = data->startx - event->x;
+	dunits = dx / (UI_UNIT_X * 1.5); // TODO: make sure this factor corresponds to menubar button sizes
+	data->newindex = (cur_index - dunits);
+	maxindex = (BLI_countlist(&ar->operators) - 1);
+	CLAMP(data->newindex, 0, maxindex);
+	
+	ED_region_tag_redraw(ar);
+}
+
+static void ui_do_drag_button_finish(const bContext *UNUSED(C), const wmEvent *UNUSED(event), ARegion *ar)
+{
+	uiHandleRegionDragData *data = ar->dragdata;
+	int cur_index = BLI_findindex(&ar->operators, data->oli);
+	OperatorListItem *oli_target = BLI_findlink(&ar->operators, data->newindex);
+	
+	if (data->newindex < cur_index) {
+		BLI_remlink(&ar->operators, data->oli);
+		BLI_insertlinkbefore(&ar->operators, oli_target, data->oli);
+	}
+	else if (data->newindex > cur_index) {
+		BLI_remlink(&ar->operators, data->oli);
+		BLI_insertlinkafter(&ar->operators, oli_target, data->oli);
+	}
+	
+	ED_region_tag_redraw(ar);
+}
+
+
+static void region_activate_drag_state(const bContext *C, ARegion *ar, uiHandleRegionDragState state);
+
+static int ui_handler_region_drag_shelf(bContext *C, const wmEvent *event, void *userdata)
+{
+	ARegion *ar = userdata;
+	uiHandleRegionDragData *data;
+	int retval = WM_UI_HANDLER_CONTINUE;
+	
+	if (event->type == MOUSEMOVE) {
+		if (ar->dragdata) {
+			data = ar->dragdata;
+			
+			if (data->state == REGION_STATE_DRAG_BUTTON) {
+				ui_do_drag_button(C, event, ar);
+			}
+			else if (data->state == REGION_STATE_DRAG_BUTTON_WAITING) {
+				if (ABS(data->startx - event->x) > UI_UNIT_X) {
+					region_activate_drag_state(C, ar, REGION_STATE_DRAG_BUTTON);
+				}
+			}
+		}
+		retval = WM_UI_HANDLER_BREAK;
+	}
+	else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+		if (ar->dragdata) {
+			data = ar->dragdata;
+			if (data->state == REGION_STATE_DRAG_BUTTON) {
+				ui_do_drag_button_finish(C, event, ar);
+				retval = WM_UI_HANDLER_BREAK;
+			}
+		}
+		region_activate_drag_state(C, ar, REGION_STATE_DRAG_EXIT);
+	}
+	
+	return retval;
+}
+
+//static void ui_handler_region_drag_shelf_remove(bContext *C, void *userdata)
+static void ui_handler_region_drag_shelf_remove(bContext *UNUSED(C), void *UNUSED(userdata))
+{
+//	ARegion *ar = userdata;
+//	region_activate_drag_state(C, ar, REGION_STATE_DRAG_EXIT);
+}
+
+static void region_activate_drag_state(const bContext *C, ARegion *ar, uiHandleRegionDragState state)
+{
+	uiHandleRegionDragData *data = ar->dragdata;
+	wmWindow *win = CTX_wm_window(C);
+	
+	if (data && data->state == state)
+		return;
+	
+	if (state == REGION_STATE_DRAG_EXIT) {
+		
+		if (data) {
+			/* deactivate the button when we've dragged, otherwise we'll get a 
+			 * global drag */
+			if (data->state == REGION_STATE_DRAG_BUTTON) {
+				uiBut *but = ui_but_find_activated(ar);
+				ui_button_active_free(C, but);
+			}
+			
+			MEM_freeN(data);
+			ar->dragdata = NULL;
+		}
+		WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_region_drag_shelf, ui_handler_region_drag_shelf_remove, ar, FALSE);
+	}
+	else if (state == REGION_STATE_DRAG_BUTTON_WAITING) {
+		if (!data) {
+			OperatorListItem *oli = NULL;
+			uiBut *but = ui_but_find_activated(ar);
+			
+			if (but->optype) {
+				oli = uiOperatorListItemPresent(&ar->operators, but->optype->idname, but->opptr ? but->opptr->data : NULL);
+				
+				if (oli) {
+					data = MEM_callocN(sizeof(uiHandleRegionDragData), "uiHandleRegionDragData");
+					data->state = REGION_STATE_DRAG_BUTTON_WAITING;
+					data->startx = win->eventstate->x;
+					data->starty = win->eventstate->y;
+					data->oli = oli;
+					ar->dragdata = (void*)data;
+					
+					WM_event_add_ui_handler(C, &win->modalhandlers, ui_handler_region_drag_shelf, ui_handler_region_drag_shelf_remove, ar);
+				}
+			}
+		}
+	}
+	else if (state == REGION_STATE_DRAG_BUTTON) {
+		if (data) data->state = state;
+	}
+	
+	ED_region_tag_redraw(ar);
+}
+
 static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(userdata))
 {
 	ARegion *ar;
@@ -7672,22 +7802,35 @@
 
 	/* either handle events for already activated button or try to activate */
 	but = ui_but_find_activated(ar);
-
+	
+	/* capture button drags in the MENU_BAR region so that we can do custom drag and drop */
+	if (ar->regiontype == RGN_TYPE_MENU_BAR) {
+		/* start drag */
+		if (but && event->type == LEFTMOUSE && event->val == KM_PRESS) {
+			region_activate_drag_state(C, ar, REGION_STATE_DRAG_BUTTON_WAITING);
+		}
+	}
+	
 	retval = ui_handler_panel_region(C, event);
 
 	if (retval == WM_UI_HANDLER_CONTINUE)
 		retval = ui_handle_list_event(C, event, ar);
 
-	if (retval == WM_UI_HANDLER_CONTINUE) {
+	/* only if there's no drag going on inside the region */
+	if (retval == WM_UI_HANDLER_CONTINUE
+//		&& (ar->dragdata == NULL || (uiHandleRegionDragData*)(ar->dragdata)->state == REGION_STATE_DRAG_BUTTON_WAITING)
+		)
+	{
 		if (but)
 			retval = ui_handle_button_event(C, event, but);
 		else
 			retval = ui_handle_button_over(C, event, ar);
 	}
 
-	/* re-enable tooltips */
+	/* re-enable tooltips, only if there's no drag going on inside the region */
 	if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy))
-		ui_blocks_set_tooltips(ar, true);
+		if (ar->dragdata == NULL)
+			ui_blocks_set_tooltips(ar, true);
 	
 	/* delayed apply callbacks */
 	ui_apply_but_funcs_after(C);

Modified: branches/soc-2013-ui_replay/source/blender/editors/interface/interface_intern.h
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/interface/interface_intern.h	2013-09-10 16:52:42 UTC (rev 60017)
+++ branches/soc-2013-ui_replay/source/blender/editors/interface/interface_intern.h	2013-09-10 18:32:38 UTC (rev 60018)
@@ -37,6 +37,7 @@
 #include "RNA_types.h"
 
 struct ARegion;
+struct OperatorListItem;
 struct bContext;
 struct IDProperty;
 struct uiHandleButtonData;
@@ -458,6 +459,24 @@
 	int direction;
 };
 
+typedef enum uiHandleRegionDragState {
+	REGION_STATE_DRAG_BUTTON_WAITING,
+	REGION_STATE_DRAG_BUTTON,
+	REGION_STATE_DRAG_EXIT
+} uiHandleRegionDragState;
+
+struct uiHandleRegionDragData {
+	/* keep track of dragging state */
+	uiHandleRegionDragState state;
+	
+	/* info for dragging */
+	int startx, starty;
+	
+	/* custom button */
+	OperatorListItem *oli;
+	int newindex;
+};
+
 uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, void *arg_but);
 
 struct ARegion *ui_tooltip_create(struct bContext *C, struct ARegion *butregion, uiBut *but);

Modified: branches/soc-2013-ui_replay/source/blender/editors/interface/interface_layout.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/interface/interface_layout.c	2013-09-10 16:52:42 UTC (rev 60017)
+++ branches/soc-2013-ui_replay/source/blender/editors/interface/interface_layout.c	2013-09-10 18:32:38 UTC (rev 60018)
@@ -1825,7 +1825,7 @@
 /********************* OperatorListItem utilities ********************/
 
 /* return 1 when an OperatorListItem with the same name and properties is already present in lb */
-int uiOperatorListItemPresent(ListBase *lb, const char *idname, IDProperty *properties)
+OperatorListItem *uiOperatorListItemPresent(ListBase *lb, const char *idname, IDProperty *properties)
 {
 	OperatorListItem *oli;
 	
@@ -1834,14 +1834,14 @@

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list