diff options
author | Ton Roosendaal <ton@blender.org> | 2008-11-24 13:45:36 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2008-11-24 13:45:36 +0300 |
commit | 41ac50b3d3ed17ead1ffd4cbba188880bb20cfea (patch) | |
tree | ce6707375fac4224ea39e615ef7fd6de64feebe5 /source | |
parent | af6b221107ab998a37bccf1e89ac96525a519b97 (diff) |
Work on gesture, some more cleaning.
- 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)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/include/BIF_glutil.h | 2 | ||||
-rw-r--r-- | source/blender/editors/include/ED_screen.h | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 31 | ||||
-rw-r--r-- | source/blender/editors/screen/glutil.c | 3 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 6 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 28 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_screen_types.h | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 22 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 26 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_gesture.c | 69 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_keymap.c | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 100 | ||||
-rw-r--r-- | source/blender/windowmanager/wm.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_types.h | 32 |
16 files changed, 279 insertions, 54 deletions
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index 3fcb88b1c49..b354591fc5f 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -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); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 3188746c599..01fac210a14 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -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); diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 074c05b050f..90f888e652d 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -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 */ diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index c9ee8e67b27..7822ada7a09 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -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; } diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 08587ddb9a5..0be29fc53c0 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -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(); } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 5c39a1b00bd..742022ea370 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -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 *************************** */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index a2272f1b5b6..ce098c0f8e7 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -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); } diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 40374f56967..c03a60ff65f 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -37,10 +37,6 @@ struct Scene; struct SpaceType; struct SpaceLink; struct ARegionType; -struct bContext; -struct wmNotifier; -struct wmWindowManager; - typedef struct bScreen { ID id; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index cb2bc80dfd2..9b2c1409887 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -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); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index adf4e2226b0..35dad1f0db2 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -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 */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index d0f812e31e6..c10faa6cadf 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -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); diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 0a927f3f191..a28eedc631e 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -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); diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 7a5ec0e4d47..610222b4372 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -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; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b8c822592df..32800ff31dc 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -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 */ diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h index ec9c56f6404..139c360dfda 100644 --- a/source/blender/windowmanager/wm.h +++ b/source/blender/windowmanager/wm.h @@ -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 */ diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index da644d77611..1edaec417c2 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -35,11 +35,11 @@ #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 @@ -259,8 +259,28 @@ /* **************** 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 */ |