More change to the gesture manager.
authorDiego Borghetti <bdiego@gmail.com>
Sat, 19 Jan 2008 21:54:33 +0000 (21:54 +0000)
committerDiego Borghetti <bdiego@gmail.com>
Sat, 19 Jan 2008 21:54:33 +0000 (21:54 +0000)
After check this a little more I make some changes to the
API and now work on the following form:
WM_gesture_init(C, type);

while() {
/* handler event, etc */
/* if something change. */
if(need_update) {
/* update the gesture data and notify about it. */
WM_gesture_update(C, data);
WM_event_add_notifier (.. WM_NOTE_GESTURE_CHANGE ..);
}
}
WM_gesture_end(C, type);

Another of the change is that now the gesture data is a link list
in the window struct, so we can have multiples "gestures" (but
of different type) at the same time.

Also take care that the "gesture data" is reusable, that mean that
only alloc it 1 time and use in all the place, that is
why don't support multiple gesture of the same type, but of course
that can be change.

source/blender/editors/screen/screen_edit.c
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_gesture.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/wm_gesture_types.h

index 1c8c6a7141f665c4893e057785963d8d768c0e94..e6d45f20c6292daa2ce043b70f0d515cbe3f2cce 100644 (file)
 #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;
 }
index a16cd0c8366787606469764e587d169124ef8e19..56fdc3e113cda4039836341e75e17fd721e6dcb0 100644 (file)
@@ -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;
 
 #
index 93bd3081f42c902d648ab3023c83f0088557ecaa..64abda4a849a1fc3b8e67e47524a58614b777257 100644 (file)
@@ -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]);
index 99f94b49537988b6752ad42b87141f25cb4b6a7e..283b269fdfc8d57c7055d10453647939f9832cbb 100644 (file)
 
 #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(!C->window)
+               return;
 
-       if(from->type==GESTURE_RECT)
-               wm_gesture_rect_copy((wmGestureRect *) to, (wmGestureRect *) from);
-       return (to);
+       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);
        }
 }
index b1b9d345c3ab53324c1fda0fb5a737bd5d876692..88408869aba569d4313a733b2f4170c34da97854 100644 (file)
@@ -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);
index e597eb9fef30cd463bb16a743115be00ee9652b3..214d10a41091e4f8e21e6a17bbb30a2ffb67135a 100644 (file)
@@ -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);
index e412080a7ef47e4e01af0a377567040db493c97b..5c8f1cc73cc2902d21d264da624bd2f36b1aee5f 100644 (file)
 #define WM_GESTURE_TYPES_H
 
 typedef struct wmGesture {
+       struct wmGesture *next, *prev;
+
        /* gesture type. */
-       short type;
+       int type;
 } wmGesture;
 
 #endif /* WM_GESTURE_TYPES_H */