Work on gesture, some more cleaning.
authorTon Roosendaal <ton@blender.org>
Mon, 24 Nov 2008 10:45:36 +0000 (10:45 +0000)
committerTon Roosendaal <ton@blender.org>
Mon, 24 Nov 2008 10:45:36 +0000 (10:45 +0000)
- Added standard "tweak" gesture operator, which can be set per region, to
  generate EVT_TWEAK events. You can configure tweaks for any mouse button
  and have handlers for such events check for modifiers etc.
  It even stores tweak direction (8 directions). Might be fun to experiment
  with tweak gestures N, S, etc. :)
  In general it can be used to replace the current tweak code in 2.48
  (std_rmouse_transform).

  Test added: on screen level it now adds LMB tweaks, if tweak-South it splits
  the area. Will be removed of course.

- Added to Border operator a property to store event used to end border with.

- Moved the "AZone" triangle drawing to the right context (area). It was on
  screen level, not respecting area-redraws. Also cleaned up drawing for it,
  and moved the "swap buffers indicator" square to look nicer. Those squares
  are only for test!

- event-match function had bad code for checking for event-value. Made a
  "KM_ANY" define so keymaps can be defined ignoring event values.

- Gesture todo: lasso, "real gesture" (like blender now has)

16 files changed:
source/blender/editors/include/BIF_glutil.h
source/blender/editors/include/ED_screen.h
source/blender/editors/interface/interface_ops.c
source/blender/editors/screen/area.c
source/blender/editors/screen/glutil.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/makesdna/DNA_screen_types.h
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_gesture.c
source/blender/windowmanager/intern/wm_keymap.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/wm.h
source/blender/windowmanager/wm_event_types.h

index 3fcb88b..b354591 100644 (file)
@@ -35,7 +35,7 @@ void fdrawline(float x1, float y1, float x2, float y2);
 void fdrawbox(float x1, float y1, float x2, float y2);
 void sdrawline(short x1, short y1, short x2, short y2);
 void sdrawtri(short x1, short y1, short x2, short y2);
-void sdrawtrifill(short x1, short y1, short x2, short y2, float r, float g, float b);
+void sdrawtrifill(short x1, short y1, short x2, short y2);
 void sdrawbox(short x1, short y1, short x2, short y2);
 
 void sdrawXORline(int x0, int y0, int x1, int y1);
index 3188746..01fac21 100644 (file)
@@ -51,6 +51,7 @@ void  ED_spacetypes_keymap(struct wmWindowManager *wm);
 /* areas */
 void   ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa);
 void   ED_area_exit(struct bContext *C, ScrArea *sa);
+void   ED_area_do_draw(struct bContext *C, ScrArea *sa);
 
 /* screens */
 void   ED_screens_initialize(struct wmWindowManager *wm);
index 074c05b..90f888e 100644 (file)
@@ -1529,7 +1529,7 @@ static void ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiActivateBut
                        if(event->shift) fac /= 10.0f;
                        if(event->alt) fac /= 20.0f;
 
-                       if(event->custom == EVT_TABLET) {
+                       if(event->custom == EVT_DATA_TABLET) {
                                wmTabletData *wmtab= event->customdata;
 
                                /* de-sensitise based on tablet pressure */
index c9ee8e6..7822ada 100644 (file)
@@ -111,6 +111,27 @@ void ED_region_do_listen(ARegion *ar, wmNotifier *note)
        }
 }
 
+/* only internal decoration, AZone for now */
+void ED_area_do_draw(bContext *C, ScrArea *sa)
+{
+       AZone *az;
+       
+       /* hrmf, screenspace for zones */
+       wm_subwindow_set(C->window, C->window->screen->mainwin);
+       
+       /* temporary viz for 'action corner' */
+       for(az= sa->actionzones.first; az; az= az->next) {
+               
+               glEnable( GL_BLEND );
+               glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+               glColor4ub(0, 0, 0, 80);
+               if(az->type==AZONE_TRI) sdrawtrifill(az->x1, az->y1, az->x2, az->y2);
+               //if(az->type==AZONE_TRI) sdrawtri(az->x1, az->y1, az->x2, az->y2);
+               glDisable( GL_BLEND );
+       }
+       
+}
+
 void ED_region_do_draw(bContext *C, ARegion *ar)
 {
        ARegionType *at= ar->type;
@@ -128,9 +149,10 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
                glClearColor(0.5, fac, 1.0f-fac, 0.0); 
                glClear(GL_COLOR_BUFFER_BIT);
                
+               /* swapbuffers indicator */
                fac= BLI_frand();
                glColor3f(fac, fac, fac);
-               glRecti(2,  2,  12,  12);
+               glRecti(20,  2,  30,  12);
                
                region_draw_emboss(ar);
        }
@@ -295,9 +317,10 @@ void area_azone_initialize(ScrArea *sa)
                        az->y1= sa->v1->vec.y+1;
                        az->x2= sa->v1->vec.x+AZONESPOT;
                        az->y2= sa->v1->vec.y+AZONESPOT;
-               } else if (az->pos==AZONE_NE) {
-                       az->x1= sa->v3->vec.x-1;
-                       az->y1= sa->v3->vec.y-1;
+               } 
+               else if (az->pos==AZONE_NE) {
+                       az->x1= sa->v3->vec.x;
+                       az->y1= sa->v3->vec.y;
                        az->x2= sa->v3->vec.x-AZONESPOT;
                        az->y2= sa->v3->vec.y-AZONESPOT;
                }
index 08587dd..0be29fc 100644 (file)
@@ -120,10 +120,9 @@ void sdrawtri(short x1, short y1, short x2, short y2)
        glEnd();
 }
 
-void sdrawtrifill(short x1, short y1, short x2, short y2, float r, float g, float b)
+void sdrawtrifill(short x1, short y1, short x2, short y2)
 {
        glBegin(GL_TRIANGLES);
-       glColor3f(r, g, b);
        sdrawtripoints(x1, y1, x2, y2);
        glEnd();
 }
index 5c39a1b..742022e 100644 (file)
@@ -768,7 +768,6 @@ static void scrarea_draw_shape_light(ScrArea *sa, char dir)
 /** screen edges drawing **/
 static void drawscredge_area(ScrArea *sa)
 {
-       AZone *az;
        short x1= sa->v1->vec.x;
        short y1= sa->v1->vec.y;
        short x2= sa->v3->vec.x;
@@ -790,11 +789,6 @@ static void drawscredge_area(ScrArea *sa)
        /* bottom border area */
        sdrawline(x1, y1, x2, y1);
        
-       /* temporary viz for 'action corner' */
-       for(az= sa->actionzones.first; az; az= az->next) {
-               if(az->type==AZONE_TRI) sdrawtrifill(az->x1, az->y1, az->x2, az->y2, .2, .2, .2);
-               //if(az->type==AZONE_TRI) sdrawtri(az->x1, az->y1, az->x2, az->y2);
-       }
 }
 
 /* ****************** EXPORTED API TO OTHER MODULES *************************** */
index a2272f1..ce098c0 100644 (file)
@@ -834,6 +834,11 @@ static int area_split_invoke(bContext *C, wmOperator *op, wmEvent *event)
                return OPERATOR_RUNNING_MODAL;
                
        }
+       else {
+               /* nonmodal for now */
+               return op->type->exec(C, op);
+       }
+       
        return OPERATOR_PASS_THROUGH;
 }
 
@@ -911,7 +916,7 @@ void ED_SCR_OT_area_split(wmOperatorType *ot)
        ot->invoke= area_split_invoke;
        ot->modal= area_split_modal;
        
-       ot->poll= ED_operator_screenactive; /* XXX should be area active */
+       ot->poll= ED_operator_areaactive;
 
        /* rna */
        prop= RNA_def_property(ot->rna, "dir", PROP_ENUM, PROP_NONE);
@@ -1227,7 +1232,15 @@ callbacks:
 
 static int border_select_do(bContext *C, wmOperator *op)
 {
-       printf("border select do\n");
+       int event_type= RNA_int_get(op->rna, "event_type");
+       
+       if(event_type==LEFTMOUSE)
+               printf("border select do select\n");
+       else if(event_type==RIGHTMOUSE)
+               printf("border select deselect\n");
+       else 
+               printf("border select do something\n");
+       
        return 1;
 }
 
@@ -1243,6 +1256,10 @@ void ED_SCR_OT_border_select(wmOperatorType *ot)
        ot->modal= WM_border_select_modal;
        
        ot->poll= ED_operator_areaactive;
+       
+       /* rna */
+       RNA_def_property(ot->rna, "event_type", PROP_INT, PROP_NONE);
+
 }
 
 
@@ -1274,10 +1291,13 @@ void ED_keymap_screen(wmWindowManager *wm)
        WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0);
        WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_area_split", EVT_ACTIONZONE, 0, 0, 0);      /* action tria */
        WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_area_join", EVT_ACTIONZONE, 0, 0, 0);       /* action tria */ 
-       WM_keymap_verify_item(&wm->windowkeymap, "ED_SCR_OT_area_rip", RKEY, KM_PRESS, KM_ALT, 0);
+       WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_area_rip", RKEY, KM_PRESS, KM_ALT, 0);
 
        /* for test only */
-       WM_keymap_verify_item(&wm->windowkeymap, "ED_SCR_OT_border_select", BKEY, KM_PRESS, 0, 0);
+       WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_border_select", BKEY, KM_PRESS, 0, 0);
+       WM_keymap_verify_item(&wm->screenkeymap, "WM_OT_tweak_gesture", LEFTMOUSE, KM_PRESS, 0, 0); /* generates event */
+
+       WM_keymap_add_item(&wm->screenkeymap, "ED_SCR_OT_area_split", EVT_TWEAK, EVT_GESTURE_S, 0, 0);
 
 }
 
index 40374f5..c03a60f 100644 (file)
@@ -37,10 +37,6 @@ struct Scene;
 struct SpaceType;
 struct SpaceLink;
 struct ARegionType;
-struct bContext;
-struct wmNotifier;
-struct wmWindowManager;
-               
 
 typedef struct bScreen {
        ID id;
index cb2bc80..9b2c140 100644 (file)
@@ -103,6 +103,9 @@ void                WM_operator_cancel              (struct bContext *C, ListBase *modalops, wmOperatorTyp
 int                    WM_border_select_invoke (struct bContext *C, wmOperator *op, struct wmEvent *event);
 int                    WM_border_select_modal  (struct bContext *C, wmOperator *op, struct wmEvent *event);
 
+                       /* default operator for arearegions, generates event */
+void           WM_OT_tweak_gesture(wmOperatorType *ot);
+
                        /* Gesture manager API */
 struct wmGesture *WM_gesture_new(struct bContext *C, struct wmEvent *event, int type);
 void           WM_gesture_end(struct bContext *C, struct wmGesture *gesture);
index adf4e22..35dad1f 100644 (file)
@@ -81,8 +81,9 @@ typedef struct wmEvent {
 #define KM_OSKEY2      128
 
 /* val */
-#define KM_PRESS       2
-#define KM_RELEASE     1
+#define KM_ANY         -1
+#define KM_RELEASE     0
+#define KM_PRESS       1
 
 
 /* ************** notifiers ****************** */
@@ -113,17 +114,20 @@ enum {
 /* ************** Gesture Manager data ************** */
 
 /* wmGesture->type */
-#define WM_GESTURE_LINE                        0
-#define WM_GESTURE_RECT                        1
-#define WM_GESTURE_CROSS_RECT  2
-#define WM_GESTURE_LASSO               3
-#define WM_GESTURE_CIRCLE              4
+#define WM_GESTURE_TWEAK               0
+#define WM_GESTURE_LINE                        1
+#define WM_GESTURE_RECT                        2
+#define WM_GESTURE_CROSS_RECT  3
+#define WM_GESTURE_LASSO               4
+#define WM_GESTURE_CIRCLE              5
 
 /* wmGesture is registered to window listbase, handled by operator callbacks */
 typedef struct wmGesture {
        struct wmGesture *next, *prev;
-       int eventtype, mode;
-       int type, swinid;
+       int event_type; /* event->type */
+       int mode;               /* for modal callback */
+       int type;               /* gesture type define */
+       int swinid;             /* initial subwindow id where it started */
        
        void *customdata;
        /* customdata for border is a recti */
index d0f812e..c10faa6 100644 (file)
@@ -223,6 +223,8 @@ void wm_draw_update(bContext *C)
                                ED_screen_refresh(C->wm, win);
 
                        for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+                               int area_do_draw= 0;
+                               
                                C->area= sa;
                                
                                for(ar=sa->regionbase.first; ar; ar= ar->next) {
@@ -232,12 +234,17 @@ void wm_draw_update(bContext *C)
                                        if(ar->do_refresh)
                                                ED_region_do_refresh(C, ar);
                                        
-                                       if(ar->swinid && ar->do_draw)
+                                       if(ar->swinid && ar->do_draw) {
                                                ED_region_do_draw(C, ar);
-
+                                               area_do_draw= 1;
+                                       }
+                                       
                                        C->region= NULL;
                                }
-
+                               /* only internal decoration, like AZone */
+                               if(area_do_draw)
+                                       ED_area_do_draw(C, sa);
+                               
                                C->area = NULL;
                        }
                        
@@ -364,10 +371,11 @@ void WM_event_remove_handlers(ListBase *handlers)
 
 static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *km)
 {
+       
        if(winevent->type!=km->type) return 0;
        
-       if(km->val) /* KM_PRESS, KM_RELEASE */
-               if(winevent->val!=km->val-1) return 0;
+       if(km->val!=KM_ANY)
+               if(winevent->val!=km->val) return 0;
        
        if(winevent->shift!=km->shift) return 0;
        if(winevent->ctrl!=km->ctrl) return 0;
@@ -648,7 +656,7 @@ void WM_event_add_message(wmWindowManager *wm, void *customdata, short customdat
 
                event.type= MESSAGE;
                if(customdata) {
-                       event.custom= EVT_MESSAGE;
+                       event.custom= EVT_DATA_MESSAGE;
                        event.customdata= customdata;
                        event.customdatafree= customdatafree;
                }
@@ -748,7 +756,7 @@ static void update_tablet_data(wmWindow *win, wmEvent *event)
                wmtab->Xtilt = td->Xtilt;
                wmtab->Ytilt = td->Ytilt;
                
-               event->custom= EVT_TABLET;
+               event->custom= EVT_DATA_TABLET;
                event->customdata= wmtab;
                event->customdatafree= 1;
        } 
@@ -812,7 +820,7 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata)
                        GHOST_TEventKeyData *kd= customdata;
                        event.type= convert_key(kd->key);
                        event.ascii= kd->ascii;
-                       event.val= (type==GHOST_kEventKeyDown);
+                       event.val= (type==GHOST_kEventKeyDown); /* XXX eventmatch uses defines, bad code... */
                        
                        /* modifiers */
                        if (event.type==LEFTSHIFTKEY || event.type==RIGHTSHIFTKEY) {
@@ -845,7 +853,7 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata)
                }
                case GHOST_kEventTimer: {
                        event.type= TIMER;
-                       event.custom= EVT_TIMER;
+                       event.custom= EVT_DATA_TIMER;
                        event.customdata= customdata;
                        wm_event_add(win, &event);
 
index 0a927f3..a28eedc 100644 (file)
@@ -26,6 +26,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include <math.h>
+
 #include "DNA_screen_types.h"
 #include "DNA_vec_types.h"
 #include "DNA_windowmanager_types.h"
@@ -55,12 +57,12 @@ wmGesture *WM_gesture_new(bContext *C, wmEvent *event, int type)
        BLI_addtail(&C->window->gesture, gesture);
        
        gesture->type= type;
-       gesture->eventtype= event->type;
+       gesture->event_type= event->type;
        gesture->swinid= C->screen->subwinactive;       /* means only in area-region context! */
        
        wm_subwindow_getorigin(C->window, gesture->swinid, &sx, &sy);
        
-       if( ELEM(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT)) {
+       if( ELEM3(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK)) {
                rcti *rect= MEM_callocN(sizeof(rcti), "gesture rect new");
                
                gesture->customdata= rect;
@@ -80,6 +82,47 @@ void WM_gesture_end(bContext *C, wmGesture *gesture)
        MEM_freeN(gesture);
 }
 
+/* for line, lasso, ... */
+void wm_gesture_point_add(bContext *C, wmGesture *gesture)
+{
+       
+}
+
+/* tweak and line gestures */
+#define TWEAK_THRESHOLD                10
+int wm_gesture_evaluate(bContext *C, wmGesture *gesture)
+{
+       if(gesture->type==WM_GESTURE_TWEAK) {
+               rcti *rect= gesture->customdata;
+               int dx= rect->xmax - rect->xmin;
+               int dy= rect->ymax - rect->ymin;
+               if(ABS(dx)+ABS(dy) > TWEAK_THRESHOLD) {
+                       int theta= (int)round(4.0f*atan2((float)dy, (float)dx)/M_PI);
+                       int val= EVT_GESTURE_W;
+                       
+                       if(theta==0) val= EVT_GESTURE_E;
+                       else if(theta==1) val= EVT_GESTURE_NE;
+                       else if(theta==2) val= EVT_GESTURE_N;
+                       else if(theta==3) val= EVT_GESTURE_NW;
+                       else if(theta==-1) val= EVT_GESTURE_SE;
+                       else if(theta==-2) val= EVT_GESTURE_S;
+                       else if(theta==-3) val= EVT_GESTURE_SW;
+                       
+                       /* debug */
+                       if(val==1) printf("tweak north\n");
+                       if(val==2) printf("tweak north-east\n");
+                       if(val==3) printf("tweak east\n");
+                       if(val==4) printf("tweak south-east\n");
+                       if(val==5) printf("tweak south\n");
+                       if(val==6) printf("tweak south-west\n");
+                       if(val==7) printf("tweak west\n");
+                       if(val==8) printf("tweak north-west\n");
+                       
+                       return val;
+               }
+       }
+       return 0;
+}
 
 
 /* ******************* gesture draw ******************* */
@@ -90,7 +133,7 @@ static void wm_gesture_draw_rect(wmWindow *win, wmGesture *gt)
        
        glEnable(GL_LINE_STIPPLE);
        glColor3ub(0, 0, 0);
-       glLineStipple(1, 0xAAAA);
+       glLineStipple(1, 0xCCCC);
        sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
        glColor3ub(255, 255, 255);
        glLineStipple(1, 0x3333);
@@ -98,13 +141,29 @@ static void wm_gesture_draw_rect(wmWindow *win, wmGesture *gt)
        glDisable(GL_LINE_STIPPLE);
 }
 
-static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
+static void wm_gesture_draw_line(wmWindow *win, wmGesture *gt)
 {
        rcti *rect= (rcti *)gt->customdata;
        
        glEnable(GL_LINE_STIPPLE);
        glColor3ub(0, 0, 0);
        glLineStipple(1, 0xAAAA);
+       sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+       glColor3ub(255, 255, 255);
+       glLineStipple(1, 0x5555);
+       sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+
+       glDisable(GL_LINE_STIPPLE);
+       
+}
+
+static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
+{
+       rcti *rect= (rcti *)gt->customdata;
+       
+       glEnable(GL_LINE_STIPPLE);
+       glColor3ub(0, 0, 0);
+       glLineStipple(1, 0xCCCC);
        sdrawline(rect->xmin - win->sizex, rect->ymin, rect->xmin + win->sizex, rect->ymin);
        sdrawline(rect->xmin, rect->ymin - win->sizey, rect->xmin, rect->ymin + win->sizey);
        
@@ -126,6 +185,8 @@ void wm_gesture_draw(wmWindow *win)
                
                if(gt->type==WM_GESTURE_RECT)
                        wm_gesture_draw_rect(win, gt);
+               else if(gt->type==WM_GESTURE_TWEAK)
+                       wm_gesture_draw_line(win, gt);
                else if(gt->type==WM_GESTURE_CROSS_RECT) {
                        if(gt->mode==1)
                                wm_gesture_draw_rect(win, gt);
index 7a5ec0e..610222b 100644 (file)
@@ -71,12 +71,11 @@ static void keymap_set(wmKeymapItem *km, short type, short val, int modifier, sh
                km->oskey= 2;   
 }
 
-/* if item was added, then replace */
+/* if item was added, then bail out */
 void WM_keymap_verify_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier)
 {
        wmKeymapItem *km;
        
-       /* if item was added, then bail out */
        for(km= lb->first; km; km= km->next)
                if(strncmp(km->idname, idname, OP_MAX_TYPENAME)==0)
                        break;
index b8c8225..32800ff 100644 (file)
@@ -48,6 +48,7 @@
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "wm.h"
 #include "wm_window.h"
 #include "wm_subwindow.h"
 #include "wm_event_system.h"
@@ -143,7 +144,16 @@ static void WM_OT_exit_blender(wmOperatorType *ot)
  * These are default callbacks for use in operators requiring gesture input
  */
 
-static void border_select_apply(bContext *C, wmOperator *op)
+/* **************** Border gesture *************** */
+
+/* Border gesture has two types:
+   1) WM_GESTURE_CROSS_RECT: starts a cross, on mouse click it changes to border 
+   2) WM_GESTURE_RECT: starts immediate as a border, on mouse click or release it ends
+
+   It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type)
+*/
+
+static void border_select_apply(bContext *C, wmOperator *op, int event_type)
 {
        wmGesture *gesture= op->customdata;
        rcti *rect= gesture->customdata;
@@ -154,6 +164,8 @@ static void border_select_apply(bContext *C, wmOperator *op)
        RNA_int_default(op->rna, "xmax", rect->xmax);
        RNA_int_default(op->rna, "ymax", rect->ymax);
        
+       RNA_int_default(op->rna, "event_type", event_type);
+       
        op->type->exec(C, op);
 }
 
@@ -205,6 +217,8 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
                        break;
                        
                case LEFTMOUSE:
+               case MIDDLEMOUSE:
+               case RIGHTMOUSE:
                        if(event->val==1) {
                                if(gesture->type==WM_GESTURE_CROSS_RECT && gesture->mode==0) {
                                        gesture->mode= 1;
@@ -212,7 +226,7 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
                                }
                        }
                        else {
-                               border_select_apply(C, op);
+                               border_select_apply(C, op, event->type);
                                border_select_end(C, op);
                                return OPERATOR_FINISHED;
                        }
@@ -224,6 +238,87 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
+/* **************** Tweak gesture *************** */
+
+static int tweak_gesture_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       op->customdata= WM_gesture_new(C, event, WM_GESTURE_TWEAK);
+       
+       /* add modal handler */
+       WM_event_add_modal_handler(&C->window->handlers, op);
+       
+       WM_event_add_notifier(C->wm, C->window, C->screen->subwinactive, WM_NOTE_GESTURE_REDRAW, 0, NULL);
+       
+       return OPERATOR_RUNNING_MODAL;
+}
+
+static void tweak_gesture_end(bContext *C, wmOperator *op)
+{
+       wmGesture *gesture= op->customdata;
+       
+       WM_gesture_end(C, gesture);     /* frees gesture itself, and unregisters from window */
+       op->customdata= NULL;
+       WM_event_remove_modal_handler(&C->window->handlers, op);
+       WM_event_add_notifier(C->wm, C->window, gesture->swinid, WM_NOTE_AREA_REDRAW, 0, NULL);
+       
+}
+
+static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+       wmGesture *gesture= op->customdata;
+       rcti *rect= gesture->customdata;
+       int sx, sy, val;
+       
+       switch(event->type) {
+               case MOUSEMOVE:
+                       
+                       wm_subwindow_getorigin(C->window, gesture->swinid, &sx, &sy);
+                       
+                       rect->xmax= event->x - sx;
+                       rect->ymax= event->y - sy;
+                       
+                       if((val= wm_gesture_evaluate(C, gesture))) {
+                               wmEvent event;
+                                       
+                               event= *(C->window->eventstate);
+                               event.type= EVT_TWEAK;
+                               event.val= val;
+                               /* mouse coords! */
+                               wm_event_add(C->window, &event);
+                               
+                               tweak_gesture_end(C, op);
+                               return OPERATOR_FINISHED;
+                       }
+                       else
+                               WM_event_add_notifier(C->wm, C->window, gesture->swinid, WM_NOTE_GESTURE_REDRAW, 0, NULL);
+                       
+                       break;
+                       
+               case LEFTMOUSE:
+               case RIGHTMOUSE:
+               case MIDDLEMOUSE:
+                       if(gesture->event_type==event->type) {
+                               wm_gesture_evaluate(C, gesture);
+                               tweak_gesture_end(C, op);
+                               return OPERATOR_FINISHED;
+                       }
+                       break;
+       }
+       return OPERATOR_RUNNING_MODAL;
+}
+
+void WM_OT_tweak_gesture(wmOperatorType *ot)
+{
+       ot->name= "Tweak Gesture";
+       ot->idname= "WM_OT_tweak_gesture";
+       
+       ot->invoke= tweak_gesture_invoke;
+       ot->modal= tweak_gesture_modal;
+
+       ot->poll= WM_operator_winactive;
+}
+
+
 /* ******************************************************* */
  
 /* called on initialize WM_exit() */
@@ -239,6 +334,7 @@ void wm_operatortype_init(void)
        WM_operatortype_append(WM_OT_save_homefile);
        WM_operatortype_append(WM_OT_window_fullscreen_toggle);
        WM_operatortype_append(WM_OT_exit_blender);
+       WM_operatortype_append(WM_OT_tweak_gesture);
 }
 
 /* default keymap for windows and screens, only call once per WM */
index ec9c56f..139c360 100644 (file)
@@ -49,6 +49,7 @@ void wm_window_keymap(wmWindowManager *wm);
 
 /* wm_gesture.c */
 void wm_gesture_draw(struct wmWindow *win);
+int wm_gesture_evaluate(bContext *C, wmGesture *gesture);
 
 #endif /* WM_H */
 
index da644d7..1edaec4 100644 (file)
 #ifndef WM_EVENT_TYPES_H
 #define WM_EVENT_TYPES_H
 
-/* custom data type */
-#define EVT_TABLET     1
-#define EVT_GESTURE    2
-#define EVT_TIMER      3
-#define EVT_MESSAGE    4
+/* customdata type */
+#define EVT_DATA_TABLET                1
+#define EVT_DATA_GESTURE       2
+#define EVT_DATA_TIMER         3
+#define EVT_DATA_MESSAGE       4
 
 #define MOUSEX         0x004   
 #define MOUSEY         0x005   
 
 /* **************** BLENDER GESTURE EVENTS ********************* */
 
-#define BORDERSELECT   0x5000
 #define EVT_ACTIONZONE 0x5001
+#define EVT_TWEAK              0x5002
+#define EVT_GESTURE            0x5003
+
+/* value of tweaks and line gestures, note, KM_ANY (-1) works for this case too */
+#define EVT_GESTURE_N          1
+#define EVT_GESTURE_NE         2
+#define EVT_GESTURE_E          3
+#define EVT_GESTURE_SE         4
+#define EVT_GESTURE_S          5
+#define EVT_GESTURE_SW         6
+#define EVT_GESTURE_W          7
+#define EVT_GESTURE_NW         8
+/* value of corner gestures */
+#define EVT_GESTURE_N_E                9
+#define EVT_GESTURE_N_W                10
+#define EVT_GESTURE_E_N                11
+#define EVT_GESTURE_E_S                12
+#define EVT_GESTURE_S_E                13
+#define EVT_GESTURE_S_W                14
+#define EVT_GESTURE_W_S                15
+#define EVT_GESTURE_W_N                16
 
 #endif /* WM_EVENT_TYPES_H */