diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 1c8c6a7141f..e6d45f20c62 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -51,17 +51,21 @@ #include "screen_intern.h" /* own module include */ /* ******************* gesture manager ******************* */ -void ed_gesture_draw_rect(wmWindow *win) +void ed_gesture_draw_rect(wmWindow *win, wmGesture *gt) { - wmGestureRect *rect= (wmGestureRect *)win->gesture; + wmGestureRect *rect= (wmGestureRect *)gt; sdrawbox(rect->x1, rect->y1, rect->x2, rect->y2); } void ed_gesture_update(wmWindow *win) { - wmGesture *gesture= (wmGesture *)win->gesture; - if(gesture->type==GESTURE_RECT) - ed_gesture_draw_rect(win); + wmGesture *gt= (wmGesture *)win->gesture.first; + + while(gt) { + if(gt->type==GESTURE_RECT) + ed_gesture_draw_rect(win, gt); + gt= gt->next; + } } /* ******************* screen vert, edge, area managing *********************** */ @@ -786,7 +790,6 @@ void ED_screen_do_listen(wmWindow *win, wmNotifier *note) case WM_NOTE_GESTURE_CHANGED: printf("WM_NOTE_GESTURE_CHANGED\n"); win->screen->do_gesture= 1; - win->gesture= WM_gesture_dup((wmGesture *) note->data); break; } } @@ -809,10 +812,8 @@ void ED_screen_gesture(wmWindow *win) { printf("gesture draw screen\n"); - if(win->gesture) { + if(win->gesture.first) { ed_gesture_update(win); - MEM_freeN(win->gesture); - win->gesture= NULL; } win->screen->do_gesture= 0; } diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index a16cd0c8366..56fdc3e113c 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -97,7 +97,7 @@ typedef struct wmWindow { ListBase handlers; /* window+screen handlers, overriding all queues */ ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */ - void *gesture; /* gesture stuff. */ + ListBase gesture; /* gesture stuff */ } wmWindow; # diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 93bd3081f42..64abda4a849 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -135,9 +135,10 @@ int OP_get_float_array(wmOperator *op, char *name, float *array, short *len); void OP_free_property(wmOperator *op); /* Gesture manager API */ -struct wmGesture *WM_gesture_new(int type); -struct wmGesture *WM_gesture_dup(struct wmGesture *from); -void WM_gesture_send(wmWindow *win, struct wmGesture *gesture); +void WM_gesture_init(bContext *C, int type); +void WM_gesture_update(bContext *C, struct wmGesture *from); +void WM_gesture_end(bContext *C, int type); +void WM_gesture_free(wmWindow *win); /* OpenGL wrappers, mimicing opengl syntax */ void wmLoadMatrix (wmWindow *win, float mat[][4]); diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 99f94b49537..283b269fdfc 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -32,20 +32,36 @@ #include "BLI_blenlib.h" +#include "BKE_global.h" + #include "WM_api.h" #include "WM_types.h" +#include "wm_event_system.h" + #include "BIF_gl.h" #include "BIF_glutil.h" -wmGesture *WM_gesture_new(int type) +wmGesture *wm_gesture_find(ListBase *list, int type) +{ + wmGesture *gt= list->first; + while(gt) { + if(gt->type==type) + return(gt); + gt= gt->next; + } + return(NULL); +} + +wmGesture *wm_gesture_new(int type) { wmGesture *gesture= NULL; wmGestureRect *rect; if(type==GESTURE_RECT) { - gesture= rect= MEM_mallocN(sizeof(wmGestureRect), "gesture rect new"); + rect= MEM_mallocN(sizeof(wmGestureRect), "gesture rect new"); + gesture= (wmGesture*) rect; gesture->type= type; rect->x1= 0; rect->y1= 0; @@ -55,6 +71,19 @@ wmGesture *WM_gesture_new(int type) return(gesture); } +void WM_gesture_init(bContext *C, int type) +{ + wmGesture *gt= NULL; + + if(C->window) { + gt= wm_gesture_find(&C->window->gesture, type); + if(!gt) { + gt= wm_gesture_new(type); + BLI_addtail(&C->window->gesture, gt); + } + } +} + void wm_gesture_rect_copy(wmGestureRect *to, wmGestureRect *from) { to->x1= from->x1; @@ -63,23 +92,46 @@ void wm_gesture_rect_copy(wmGestureRect *to, wmGestureRect *from) to->y2= from->y2; } -wmGesture *WM_gesture_dup(wmGesture *from) +void WM_gesture_update(bContext *C, wmGesture *from) { - wmGesture *to= WM_gesture_new(from->type); + wmGesture *to; - if(from->type==GESTURE_RECT) - wm_gesture_rect_copy((wmGestureRect *) to, (wmGestureRect *) from); - return (to); + if(!C->window) + return; + + to= wm_gesture_find(&C->window->gesture, from->type); + if(!to) + return; + + printf("found gesture!!\n"); + if(to->type==GESTURE_RECT) + wm_gesture_rect_copy((wmGestureRect*)to, (wmGestureRect*)from); } -void WM_gesture_send(wmWindow *win, wmGesture *gesture) +void WM_gesture_free(wmWindow *win) { + /* Now don't have multiple struct so + * a simple BLI_freelistN is what we need. + */ + BLI_freelistN(&win->gesture); +} + +void WM_gesture_end(bContext *C, int type) +{ + wmGesture *gt; wmGestureRect *rect; wmBorderSelect *wmbor; wmEvent event; - if(gesture->type==GESTURE_RECT) { - rect= (wmGestureRect*)gesture; + if(!C->window) + return; + + gt= wm_gesture_find(&C->window->gesture, type); + if(!gt) + return; + + if(gt->type==GESTURE_RECT) { + rect= (wmGestureRect*)gt; wmbor= MEM_mallocN(sizeof(wmBorderSelect), "border select"); wmbor->x1= rect->x1; @@ -90,6 +142,6 @@ void WM_gesture_send(wmWindow *win, wmGesture *gesture) event.type= BORDERSELECT; event.custom= EVT_GESTURE; event.customdata= wmbor; - wm_event_add(win, &event); + wm_event_add(C->window, &event); } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b1b9d345c3a..88408869aba 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -135,24 +135,26 @@ static int border_select_init(bContext *C, wmOperator *op) { OP_set_int(op, "start_x", op->veci.x); OP_set_int(op, "start_y", op->veci.y); + WM_gesture_init(C, GESTURE_RECT); return 1; } static int border_select_exec(bContext *C, wmOperator *op) { - wmGestureRect *rect; + wmGestureRect rect; int x, y; OP_get_int(op, "start_x", &x); OP_get_int(op, "start_y", &y); - rect= (wmGestureRect *) WM_gesture_new(GESTURE_RECT); - rect->x1= x; - rect->y1= y; - rect->x2= op->veci.x; - rect->y2= op->veci.y; - - WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_GESTURE_CHANGED, 0, rect); + rect.gesture.next= rect.gesture.prev= NULL; + rect.gesture.type= GESTURE_RECT; + rect.x1= x; + rect.y1= y; + rect.x2= op->veci.x; + rect.y2= op->veci.y; + WM_gesture_update(C, (wmGesture *) &rect); + WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_GESTURE_CHANGED, GESTURE_RECT, NULL); return 1; } @@ -189,19 +191,20 @@ static int border_select_modal(bContext *C, wmOperator *op, wmEvent *event) break; case LEFTMOUSE: if(event->val==0) { - wmGestureRect *rect; + wmGestureRect rect; int x, y; OP_get_int(op, "start_x", &x); OP_get_int(op, "start_y", &y); - rect= (wmGestureRect *) WM_gesture_new(GESTURE_RECT); - rect->x1= x; - rect->y1= y; - rect->x2= op->veci.x; - rect->y2= op->veci.y; - WM_gesture_send(C->window, (wmGesture *) rect); - MEM_freeN(rect); + rect.gesture.next= rect.gesture.prev= NULL; + rect.gesture.type= GESTURE_RECT; + rect.x1= x; + rect.y1= y; + rect.x2= op->veci.x; + rect.y2= op->veci.y; + WM_gesture_update(C, (wmGesture*)&rect); + WM_gesture_end(C, GESTURE_RECT); border_select_exit(C, op); WM_event_remove_modal_handler(&C->window->handlers, op); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index e597eb9fef3..214d10a4109 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -106,7 +106,8 @@ void wm_window_free(bContext *C, wmWindow *win) /* XXX free screens */ if(win->eventstate) MEM_freeN(win->eventstate); - + + WM_gesture_free(win); wm_event_free_handlers(&win->handlers); wm_event_free_all(win); wm_subwindows_free(win); diff --git a/source/blender/windowmanager/wm_gesture_types.h b/source/blender/windowmanager/wm_gesture_types.h index e412080a7ef..5c8f1cc73cc 100644 --- a/source/blender/windowmanager/wm_gesture_types.h +++ b/source/blender/windowmanager/wm_gesture_types.h @@ -30,8 +30,10 @@ #define WM_GESTURE_TYPES_H typedef struct wmGesture { + struct wmGesture *next, *prev; + /* gesture type. */ - short type; + int type; } wmGesture; #endif /* WM_GESTURE_TYPES_H */