2.5
authorTon Roosendaal <ton@blender.org>
Tue, 21 Jul 2009 11:03:07 +0000 (11:03 +0000)
committerTon Roosendaal <ton@blender.org>
Tue, 21 Jul 2009 11:03:07 +0000 (11:03 +0000)
Modal keymaps.

I've tried to make it as simple as possible, yet still using sufficient facilities to enable self-documenting UIs, saving/reading in files, and proper Python support.

The simplicity is: the 'modal keymap' just checks an event, uses event matching similarly to other keymap matching, and if there's a match it changes the event type, and sets the event value to what the modal keymap has defined. The event values are being defined using EnumPropertyItem structs, so the UI will be able to show all options in self-documenting way.
This system also allows to still handle hardcoded own events.

Tech doc:

1) define keymap
- Create map with unique name, WM_modalkeymap_add()
- Give map property definitions (EnumPropertyItem *)
  This only for UI, so user can get information on available options

2) items
- WM_modalkeymap_add_item(): give it an enum value for events

3) activate
- In keymap definition code, assign the modal keymap to operatortype
  WM_modalkeymap_assign()

4) event manager
- The event handler will check for modal keymap, if so:
  - If the modal map has a match:
    - Sets event->type to EVT_MODAL_MAP
    - Sets event->val to the enum value

5) modal handler
- If event type is EVT_MODAL_MAP:
  - Check event->val, handle it
- Other events can just be handled still

Two examples added in the code:

editors/transform/transform.c: transform_modal_keymap()
editors/screen/screen_ops.c: keymap_modal_set()

Also: to support 'key release' the define KM_RELEASE now is officially
used in event manager, this is not '0', so don't check key events with
the old convention if(event->val) but use if(event->val==KM_PRESS)

source/blender/editors/screen/screen_ops.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_ops.c
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_keymap.c
source/blender/windowmanager/wm_event_types.h

index 5cf1ffb99152972829f820870eec98153c8ea1a7..e13e27412b8dfb3dd5382a8c7f4d670dbef7d2be 100644 (file)
 
 #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);
 }
 
index 0d29f39e478e13fb0621aae1923d7b85e9cfd817..35915c96f3c038d46d71090ebb176ac30dce907e 100644 (file)
@@ -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;
index db78632e76af833226571f34d2de0f7e4100c718..efa60b15293c63acbfe84735f30a2c3c2afb56ee 100644 (file)
@@ -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;
 
index 7d6112b03deab36fa737237e4071d5cc1dcb3733..081e9589fb8d46f8b39e5380117c98eb72ab8d9b 100644 (file)
@@ -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:
index 9d36882058e5b36f128a334e782321c6212c7183..895bc943e9f3d3d1e1c3c9ae96e43c4d10974606 100644 (file)
@@ -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 */
index 609d599a09a014216abd37b824dca0557c744f5d..542a747d454bddf311fc796ad1f15cccfeddfb3c 100644 (file)
@@ -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);
index ffd1054d9548f90dae5a84de59300604c734cfe6..0df0679f98bc2e6d07fe916a7e79f5463c8515cc 100644 (file)
@@ -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;
index b914e63788d11a46e2126828733df4894b2a9ea3..764b209d7557dd07344513c14e602fb89803e1d0 100644 (file)
@@ -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)
index 39c267b132c38642c4007916a697c932814f830a..6f64cdbde32c2aa536ff61d930e08936f508988e 100644 (file)
 #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 */