[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