diff options
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 70 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.c | 119 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 5 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_ops.c | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_windowmanager_types.h | 24 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 9 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 26 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_keymap.c | 57 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_types.h | 4 |
9 files changed, 288 insertions, 30 deletions
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 5cf1ffb9915..e13e27412b8 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -76,6 +76,11 @@ #include "screen_intern.h" /* own module include */ +#define KM_MODAL_CANCEL 1 +#define KM_MODAL_APPLY 2 +#define KM_MODAL_STEP10 3 +#define KM_MODAL_STEP10_OFF 4 + /* ************** Exported Poll tests ********************** */ int ED_operator_regionactive(bContext *C) @@ -719,7 +724,7 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot) */ typedef struct sAreaMoveData { - int bigger, smaller, origval; + int bigger, smaller, origval, step; char dir; } sAreaMoveData; @@ -876,32 +881,40 @@ static int area_move_cancel(bContext *C, wmOperator *op) /* modal callback for while moving edges */ static int area_move_modal(bContext *C, wmOperator *op, wmEvent *event) { - sAreaMoveData *md; + sAreaMoveData *md= op->customdata; int delta, x, y; - md= op->customdata; - - x= RNA_int_get(op->ptr, "x"); - y= RNA_int_get(op->ptr, "y"); - /* execute the events */ switch(event->type) { case MOUSEMOVE: + + x= RNA_int_get(op->ptr, "x"); + y= RNA_int_get(op->ptr, "y"); + delta= (md->dir == 'v')? event->x - x: event->y - y; + if(md->step) delta= delta - (delta % md->step); RNA_int_set(op->ptr, "delta", delta); area_move_apply(C, op); break; - case LEFTMOUSE: - if(event->val==0) { - area_move_exit(C, op); - return OPERATOR_FINISHED; - } - break; + case EVT_MODAL_MAP: - case ESCKEY: - return area_move_cancel(C, op); + switch (event->val) { + case KM_MODAL_APPLY: + area_move_exit(C, op); + return OPERATOR_FINISHED; + + case KM_MODAL_CANCEL: + return area_move_cancel(C, op); + + case KM_MODAL_STEP10: + md->step= 10; + break; + case KM_MODAL_STEP10_OFF: + md->step= 0; + break; + } } return OPERATOR_RUNNING_MODAL; @@ -2877,6 +2890,31 @@ void ED_operatortypes_screen(void) } +static void keymap_modal_set(wmWindowManager *wm) +{ + static EnumPropertyItem modal_items[] = { + {KM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, + {KM_MODAL_APPLY, "APPLY", 0, "Apply", ""}, + {KM_MODAL_STEP10, "STEP10", 0, "Steps on", ""}, + {KM_MODAL_STEP10_OFF, "STEP10_OFF", 0, "Steps off", ""}, + {0, NULL, 0, NULL, NULL}}; + wmKeyMap *keymap; + + /* Standard Modal keymap ------------------------------------------------ */ + keymap= WM_modalkeymap_add(wm, "Standard Modal Map", modal_items); + + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_CANCEL); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, KM_MODAL_APPLY); + WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_APPLY); + WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, KM_MODAL_APPLY); + + WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_STEP10); + WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, KM_MODAL_STEP10_OFF); + + WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move"); + +} + /* called in spacetypes.c */ void ED_keymap_screen(wmWindowManager *wm) { @@ -2948,5 +2986,7 @@ void ED_keymap_screen(wmWindowManager *wm) /* play (forward and backwards) */ WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0)->ptr, "reverse", 1); + + keymap_modal_set(wm); } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 0d29f39e478..35915c96f3c 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -496,6 +496,63 @@ static char *transform_to_undostr(TransInfo *t) /* ************************************************* */ +/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ +#define TFM_MODAL_CANCEL 1 +#define TFM_MODAL_CONFIRM 2 +#define TFM_MODAL_TRANSLATE 3 +#define TFM_MODAL_ROTATE 4 +#define TFM_MODAL_RESIZE 5 +#define TFM_MODAL_SNAP_GEARS 6 +#define TFM_MODAL_SNAP_GEARS_OFF 7 + +/* called in transform_ops.c, on each regeneration of keymaps */ +void transform_modal_keymap(wmWindowManager *wm) +{ + static EnumPropertyItem modal_items[] = { + {TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, + {TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Translate", ""}, + {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""}, + {TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""}, + {TFM_MODAL_SNAP_GEARS, "SNAP_GEARS", 0, "Snap On", ""}, + {TFM_MODAL_SNAP_GEARS_OFF, "SNAP_GEARS_OFF", 0, "Snap Off", ""}, + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(wm, "Transform Modal Map"); + + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(wm, "Transform Modal Map", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CANCEL); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, TFM_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM); + + WM_modalkeymap_add_item(keymap, GKEY, KM_PRESS, 0, 0, TFM_MODAL_TRANSLATE); + WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, TFM_MODAL_ROTATE); + WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, TFM_MODAL_RESIZE); + + WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_SNAP_GEARS); + WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, TFM_MODAL_SNAP_GEARS_OFF); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "TFM_OT_transform"); + WM_modalkeymap_assign(keymap, "TFM_OT_translate"); + WM_modalkeymap_assign(keymap, "TFM_OT_rotate"); + WM_modalkeymap_assign(keymap, "TFM_OT_tosphere"); + WM_modalkeymap_assign(keymap, "TFM_OT_resize"); + WM_modalkeymap_assign(keymap, "TFM_OT_shear"); + WM_modalkeymap_assign(keymap, "TFM_OT_warp"); + WM_modalkeymap_assign(keymap, "TFM_OT_shrink_fatten"); + WM_modalkeymap_assign(keymap, "TFM_OT_tilt"); + WM_modalkeymap_assign(keymap, "TFM_OT_trackball"); + +} + + void transformEvent(TransInfo *t, wmEvent *event) { float mati[3][3] = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}; @@ -513,7 +570,67 @@ void transformEvent(TransInfo *t, wmEvent *event) applyMouseInput(t, &t->mouse, t->mval, t->values); } - if (event->val) { + /* handle modal keymap first */ + if (event->type == EVT_MODAL_MAP) { + switch (event->val) { + case TFM_MODAL_CANCEL: + t->state = TRANS_CANCEL; + break; + case TFM_MODAL_CONFIRM: + t->state = TRANS_CONFIRM; + break; + + case TFM_MODAL_TRANSLATE: + /* only switch when... */ + if( ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) { + resetTransRestrictions(t); + restoreTransObjects(t); + initTranslation(t); + initSnapping(t, NULL); // need to reinit after mode change + t->redraw = 1; + } + break; + case TFM_MODAL_ROTATE: + /* only switch when... */ + if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { + + resetTransRestrictions(t); + + if (t->mode == TFM_ROTATION) { + restoreTransObjects(t); + initTrackball(t); + } + else { + restoreTransObjects(t); + initRotation(t); + } + initSnapping(t, NULL); // need to reinit after mode change + t->redraw = 1; + } + break; + case TFM_MODAL_RESIZE: + /* only switch when... */ + if( ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) { + resetTransRestrictions(t); + restoreTransObjects(t); + initResize(t); + initSnapping(t, NULL); // need to reinit after mode change + t->redraw = 1; + } + break; + + case TFM_MODAL_SNAP_GEARS: + t->modifiers |= MOD_SNAP_GEARS; + t->redraw = 1; + break; + case TFM_MODAL_SNAP_GEARS_OFF: + t->modifiers &= ~MOD_SNAP_GEARS; + t->redraw = 1; + break; + } + } + /* else do non-mapped events */ + else if (event->val==KM_PRESS) { switch (event->type){ case RIGHTMOUSE: t->state = TRANS_CANCEL; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index db78632e76a..efa60b15293 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -47,6 +47,7 @@ struct bConstraint; struct BezTriple; struct wmOperatorType; struct wmOperator; +struct wmWindowManager; struct bContext; struct wmEvent; struct wmTimer; @@ -482,9 +483,11 @@ int Mirror(TransInfo *t, short mval[2]); void initAlign(TransInfo *t); int Align(TransInfo *t, short mval[2]); - void drawPropCircle(const struct bContext *C, TransInfo *t); +void transform_modal_keymap(struct wmWindowManager *wm); + + /*********************** transform_conversions.c ********** */ struct ListBase; diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 7d6112b03de..081e9589fb8 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -587,6 +587,10 @@ void transform_operatortypes(void) void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid) { wmKeymapItem *km; + + /* transform.c, only adds modal map once, checks if it's there */ + transform_modal_keymap(wm); + switch(spaceid) { case SPACE_VIEW3D: diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 9d36882058e..895bc943e9f 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -41,6 +41,7 @@ struct wmEvent; struct wmGesture; struct wmOperatorType; struct wmOperator; +struct wmKeyMap; /* forwards */ struct bContext; @@ -54,6 +55,10 @@ struct PointerRNA; struct ReportList; struct Report; +#define OP_MAX_TYPENAME 64 +#define KMAP_MAX_NAME 64 + + typedef enum ReportType { RPT_DEBUG = 1<<0, RPT_INFO = 1<<1, @@ -198,14 +203,16 @@ typedef struct wmOperatorType { struct StructRNA *srna; short flag; - + + /* pointer to modal keymap, do not free! */ + struct wmKeyMap *modalkeymap; + /* only used for operators defined with python * use to store pointers to python functions */ void *pyop_data; } wmOperatorType; -#define OP_MAX_TYPENAME 64 /* partial copy of the event, for matching by eventhandler */ typedef struct wmKeymapItem { @@ -219,10 +226,9 @@ typedef struct wmKeymapItem { short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */ short keymodifier; /* rawkey modifier */ - short pad; + short propvalue; /* if used, the item is from modal map */ } wmKeymapItem; -#define KMAP_MAX_NAME 64 /* stored in WM, the actively used keymaps */ typedef struct wmKeyMap { @@ -231,8 +237,13 @@ typedef struct wmKeyMap { ListBase keymap; char nameid[64]; /* global editor keymaps, or for more per space/region */ - int spaceid; /* same IDs as in DNA_space_types.h */ - int regionid; /* see above */ + short spaceid; /* same IDs as in DNA_space_types.h */ + short regionid; /* see above */ + + short is_modal; /* modal map, not using operatornames */ + short pad; + + void *items; /* struct EnumPropertyItem for now */ } wmKeyMap; @@ -250,6 +261,7 @@ typedef struct wmOperator { void *customdata; /* custom storage, only while operator runs */ struct PointerRNA *ptr; /* rna pointer to access properties */ struct ReportList *reports; /* errors and warnings storage */ + } wmOperator; /* operator type exec(), invoke() modal(), return values */ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 609d599a09a..542a747d454 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -40,6 +40,7 @@ struct wmJob; struct wmNotifier; struct rcti; struct PointerRNA; +struct EnumPropertyItem; typedef struct wmJob wmJob; @@ -79,7 +80,13 @@ wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier); void WM_keymap_tweak (ListBase *lb, short type, short val, int modifier, short keymodifier); ListBase *WM_keymap_listbase (struct wmWindowManager *wm, const char *nameid, - int spaceid, int regionid); + short spaceid, short regionid); + +wmKeyMap *WM_modalkeymap_add(struct wmWindowManager *wm, const char *nameid, struct EnumPropertyItem *items); +wmKeyMap *WM_modalkeymap_get(struct wmWindowManager *wm, const char *nameid); +void WM_modalkeymap_add_item(wmKeyMap *km, short type, short val, int modifier, short keymodifier, short value); +void WM_modalkeymap_assign(wmKeyMap *km, const char *opname); + const char *WM_key_event_string(short type); char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ffd1054d954..0df0679f98b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -652,6 +652,23 @@ static int wm_event_always_pass(wmEvent *event) return ELEM5(event->type, TIMER, TIMER0, TIMER1, TIMER2, TIMERJOBS); } +/* operator exists */ +static void wm_event_modalkeymap(wmOperator *op, wmEvent *event) +{ + if(op->type->modalkeymap) { + wmKeymapItem *kmi; + + for(kmi= op->type->modalkeymap->keymap.first; kmi; kmi= kmi->next) { + if(wm_eventmatch(event, kmi)) { + + event->type= EVT_MODAL_MAP; + event->val= kmi->propvalue; + printf("found modal event %s %d\n", kmi->idname, kmi->propvalue); + } + } + } +} + /* Warning: this function removes a modal handler, when finished */ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHandler *handler, wmEvent *event, PointerRNA *properties) { @@ -668,8 +685,9 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand ARegion *region= CTX_wm_region(C); wm_handler_op_context(C, handler); - wm_region_mouse_co(C, event); + wm_event_modalkeymap(op, event); + retval= ot->modal(C, op, event); /* putting back screen context, reval can pass trough after modal failures! */ @@ -1446,7 +1464,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); /* XXX eventmatch uses defines, bad code... */ + event.val= (type==GHOST_kEventKeyDown)?KM_PRESS:KM_RELEASE; /* exclude arrow keys, esc, etc from text input */ if(type==GHOST_kEventKeyUp || (event.ascii<32 && event.ascii>14)) @@ -1474,10 +1492,10 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata) event.oskey= evt->oskey = 3; // define? } - /* if test_break set, it catches this. Keep global for now? */ + /* if test_break set, it catches this. XXX Keep global for now? */ if(event.type==ESCKEY) G.afbreek= 1; - + wm_event_add(win, &event); break; diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index b914e63788d..764b209d755 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -132,7 +132,7 @@ wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short v space/region ids are same as DNA_space_types.h */ /* gets free'd in wm.c */ -ListBase *WM_keymap_listbase(wmWindowManager *wm, const char *nameid, int spaceid, int regionid) +static wmKeyMap *wm_keymap_add(wmWindowManager *wm, const char *nameid, short spaceid, short regionid) { wmKeyMap *km; @@ -140,7 +140,7 @@ ListBase *WM_keymap_listbase(wmWindowManager *wm, const char *nameid, int spacei if(km->spaceid==spaceid && km->regionid==regionid) if(0==strncmp(nameid, km->nameid, KMAP_MAX_NAME)) break; - + if(km==NULL) { km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list"); BLI_strncpy(km->nameid, nameid, KMAP_MAX_NAME); @@ -149,9 +149,62 @@ ListBase *WM_keymap_listbase(wmWindowManager *wm, const char *nameid, int spacei BLI_addtail(&wm->keymaps, km); } + return km; +} + +ListBase *WM_keymap_listbase(wmWindowManager *wm, const char *nameid, short spaceid, short regionid) +{ + wmKeyMap *km= wm_keymap_add(wm, nameid, spaceid, regionid); return &km->keymap; } +/* ****************** modal keymaps ************ */ + +/* modal maps get linked to a running operator, and filter the keys before sending to modal() callback */ + +wmKeyMap *WM_modalkeymap_add(wmWindowManager *wm, const char *nameid, EnumPropertyItem *items) +{ + wmKeyMap *km= wm_keymap_add(wm, nameid, 0, 0); + km->is_modal= 1; + km->items= items; + + return km; +} + +wmKeyMap *WM_modalkeymap_get(wmWindowManager *wm, const char *nameid) +{ + wmKeyMap *km; + + for(km= wm->keymaps.first; km; km= km->next) + if(km->is_modal) + if(0==strncmp(nameid, km->nameid, KMAP_MAX_NAME)) + break; + + return km; +} + + +void WM_modalkeymap_add_item(wmKeyMap *km, short type, short val, int modifier, short keymodifier, short value) +{ + wmKeymapItem *kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); + + BLI_addtail(&km->keymap, kmi); + kmi->propvalue= value; + + keymap_event_set(kmi, type, val, modifier, keymodifier); +} + +void WM_modalkeymap_assign(wmKeyMap *km, const char *opname) +{ + wmOperatorType *ot= WM_operatortype_find(opname, 0); + + if(ot) + ot->modalkeymap= km; + else + printf("error: modalkeymap_assign, unknown operator %s\n", opname); +} + + /* ***************** get string from key events **************** */ const char *WM_key_event_string(short type) diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 39c267b132c..6f64cdbde32 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -238,7 +238,11 @@ #define EVT_FILESELECT_EXEC 3 #define EVT_FILESELECT_CANCEL 4 +/* event->type */ #define EVT_BUT_OPEN 0x5021 +#define EVT_MODAL_MAP 0x5022 + + #endif /* WM_EVENT_TYPES_H */ |