diff options
22 files changed, 353 insertions, 207 deletions
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 129093f6078..49e6b20725d 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -40,13 +40,15 @@ struct wmWindowManager; struct ListBase; /* spacetype has everything stored to get an editor working, it gets initialized via -spacetypes_init() in editors/area/spacetypes.c */ + ED_spacetypes_init() in editors/area/spacetypes.c */ /* an editor in Blender is a combined ScrArea + SpaceType + SpaceData */ +#define BKE_ST_MAXNAME 32 + typedef struct SpaceType { struct SpaceType *next, *prev; - char name[32]; /* for menus */ + char name[BKE_ST_MAXNAME]; /* for menus */ int spaceid; /* unique space identifier */ int iconid; /* icon lookup for menus */ @@ -56,7 +58,7 @@ typedef struct SpaceType { void (*free)(struct SpaceLink *); /* init is to cope with internal contextual changes, adds handlers, - * sets screarea regions */ + * creates/sets screarea regions */ void (*init)(struct wmWindowManager *, struct ScrArea *); /* refresh is for external bContext changes */ void (*refresh)(struct bContext *, struct ScrArea *); @@ -66,23 +68,35 @@ typedef struct SpaceType { /* register operator types on startup */ void (*operatortypes)(void); - /* add default items to keymap */ + /* add default items to WM keymap */ void (*keymap)(struct wmWindowManager *); + /* region type definitions */ + ListBase regiontypes; + /* read and write... */ } SpaceType; -/* region type gets allocated and freed in spacetype init/free callback */ -/* data storage for regions is in space struct (also width/height of regions!) */ +/* region types are also defined using spacetypes_init, via a callback */ + typedef struct ARegionType { + struct ARegionType *next, *prev; + + int regionid; /* unique identifier within this space */ void (*init)(const struct bContext *, struct ARegion *); /* add handlers, stuff you only do once or on area/region changes */ - void (*refresh)(const struct bContext *, struct ARegion *); /* refresh to match contextual changes */ + void (*refresh)(const struct bContext *, struct ARegion *); /* refresh to match contextual changes */ void (*draw)(const struct bContext *, struct ARegion *); /* draw entirely, windowsize changes should be handled here */ void (*listener)(struct ARegion *, struct wmNotifier *); void (*free)(struct ARegion *); + + /* register operator types on startup */ + void (*operatortypes)(void); + /* add default items to keymap */ + void (*keymap)(struct wmWindowManager *); + } ARegionType; @@ -90,9 +104,13 @@ void BKE_screen_area_free(struct ScrArea *sa); void BKE_area_region_free(struct ARegion *ar); void free_screen(struct bScreen *sc); +/* spacetypes */ struct SpaceType *BKE_spacetype_from_id(int spaceid); const struct ListBase *BKE_spacetypes_list(void); void BKE_spacetype_register(struct SpaceType *st); +void BKE_spacetypes_free(void); /* only for quitting blender */ + +/* spacedata */ void BKE_spacedata_freelist(ListBase *lb); void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2); diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index b63d63c925c..e5625fa03e0 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -77,6 +77,7 @@ #include "BKE_node.h" #include "BKE_object.h" #include "BKE_scene.h" +#include "BKE_screen.h" #include "BKE_sound.h" #include "BLI_editVert.h" @@ -166,6 +167,7 @@ void pushpop_test() /* ********** free ********** */ +/* only to be called on exit blender */ void free_blender(void) { /* samples are in a global list..., also sets G.main->sound->sample NULL */ @@ -174,6 +176,8 @@ void free_blender(void) free_main(G.main); G.main= NULL; + BKE_spacetypes_free(); /* after free main, it uses space callbacks */ + IMB_freeImBufdata(); /* imbuf lib */ free_nodesystem(); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 266a387732e..8332e7baea1 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -31,8 +31,11 @@ #include <stdio.h> #include <math.h> +#include "MEM_guardedalloc.h" + #include "DNA_screen_types.h" #include "DNA_space_types.h" + #include "BLI_blenlib.h" #include "BKE_screen.h" @@ -41,9 +44,27 @@ #include "BPY_extern.h" #endif +/* ************ Spacetype/regiontype handling ************** */ + /* keep global; this has to be accessible outside of windowmanager */ static ListBase spacetypes= {NULL, NULL}; +/* not SpaceType itself */ +static void spacetype_free(SpaceType *st) +{ + BLI_freelistN(&st->regiontypes); +} + +void BKE_spacetypes_free(void) +{ + SpaceType *st; + + for(st= spacetypes.first; st; st= st->next) + spacetype_free(st); + + BLI_freelistN(&spacetypes); +} + SpaceType *BKE_spacetype_from_id(int spaceid) { SpaceType *st; @@ -62,9 +83,21 @@ const ListBase *BKE_spacetypes_list() void BKE_spacetype_register(SpaceType *st) { + SpaceType *stype; + + /* sanity check */ + stype= BKE_spacetype_from_id(st->spaceid); + if(stype) { + printf("error: redefinition of spacetype %s\n", stype->name); + spacetype_free(stype); + MEM_freeN(stype); + } + BLI_addtail(&spacetypes, st); } +/* ***************** Space handling ********************** */ + void BKE_spacedata_freelist(ListBase *lb) { SpaceLink *sl; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 75733e8d6d1..71ef913e488 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3784,11 +3784,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) } wm->operators.first= wm->operators.last= NULL; - wm->windowkeymap.first= wm->windowkeymap.last= NULL; - wm->screenkeymap.first= wm->screenkeymap.last= NULL; - wm->view2dkeymap.first= wm->view2dkeymap.last= NULL; - wm->uikeymap.first= wm->uikeymap.last= NULL; - wm->timekeymap.first= wm->timekeymap.last= NULL; + wm->keymaps.first= wm->keymaps.last= NULL; wm->queue.first= wm->queue.last= NULL; wm->reports.first= wm->reports.last= NULL; diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 2514c4c90fd..2c86b5076b0 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -36,6 +36,8 @@ struct wmWindowManager; struct wmWindow; struct wmNotifier; +struct SpaceType; +struct AreagionType; /* regions */ void ED_region_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ARegion *ar); @@ -48,6 +50,7 @@ void ED_region_pixelspace(const struct bContext *C, ARegion *ar); /* spaces */ void ED_spacetypes_init(void); void ED_spacetypes_keymap(struct wmWindowManager *wm); +struct ARegionType *ED_regiontype_from_id(struct SpaceType *st, int regionid); /* areas */ void ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa); diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 32bebab2180..a256a207e70 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -3511,8 +3511,8 @@ void ui_operatortypes(void) void UI_keymap(wmWindowManager *wm) { - ui_operatortypes(); + ListBase *keymap= WM_keymap_listbase(wm, "Interface", 0, 0); - WM_keymap_add_item(&wm->uikeymap, "ED_UI_OT_button_activate", MOUSEMOVE, 0, 0, 0); + WM_keymap_add_item(keymap, "ED_UI_OT_button_activate", MOUSEMOVE, 0, 0, 0); } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index f7029700f9c..fec3038ca88 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -277,7 +277,7 @@ static void ui_tooltip_region_free(ARegion *ar) ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) { - static ARegionType type={NULL, NULL, NULL, NULL, NULL}; + static ARegionType type; ARegion *ar; uiTooltipData *data; int x1, x2, y1, y2, winx, winy; @@ -288,6 +288,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* create area region */ ar= ui_add_temporary_region(C->window->screen); + memset(&type, 0, sizeof(ARegionType)); type.draw= ui_tooltip_region_draw; type.free= ui_tooltip_region_free; ar->type= &type; @@ -596,7 +597,8 @@ static void ui_block_region_free(ARegion *ar) uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut *but, uiBlockFuncFP block_func, void *arg) { - static ARegionType type={NULL, NULL, NULL, NULL, NULL}; + static ARegionType type; + ListBase *keymap= WM_keymap_listbase(C->wm, "Interface", 0, 0); ARegion *ar; uiBlock *block; uiBut *bt; @@ -609,11 +611,12 @@ uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut * /* create area region */ ar= ui_add_temporary_region(C->window->screen); + memset(&type, 0, sizeof(ARegionType)); type.draw= ui_block_region_draw; type.free= ui_block_region_free; ar->type= &type; - WM_event_add_keymap_handler(&ar->handlers, &C->wm->uikeymap); + WM_event_add_keymap_handler(&ar->handlers, keymap); handle->region= ar; ar->regiondata= handle; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index d784b1c7743..57264bb1342 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1160,27 +1160,27 @@ void ui_view2d_operatortypes(void) void UI_view2d_keymap(wmWindowManager *wm) { - ui_view2d_operatortypes(); + ListBase *keymap= WM_keymap_listbase(wm, "View2D", 0, 0); /* pan/scroll */ - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_rightscroll", WHEELDOWNMOUSE, KM_ANY, KM_CTRL, 0); - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_leftscroll", WHEELUPMOUSE, KM_ANY, KM_CTRL, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_view_rightscroll", WHEELDOWNMOUSE, KM_ANY, KM_CTRL, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_view_leftscroll", WHEELUPMOUSE, KM_ANY, KM_CTRL, 0); - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_downscroll", WHEELDOWNMOUSE, KM_ANY, KM_SHIFT, 0); - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_upscroll", WHEELUPMOUSE, KM_ANY, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_view_downscroll", WHEELDOWNMOUSE, KM_ANY, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_view_upscroll", WHEELUPMOUSE, KM_ANY, KM_SHIFT, 0); /* zoom - single step */ - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_zoomout", WHEELUPMOUSE, KM_ANY, 0, 0); - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_zoomin", WHEELDOWNMOUSE, KM_ANY, 0, 0); - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_zoomout", PADMINUS, KM_PRESS, 0, 0); - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_zoomin", PADPLUSKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_view_zoomout", WHEELUPMOUSE, KM_ANY, 0, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_view_zoomin", WHEELDOWNMOUSE, KM_ANY, 0, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_view_zoomout", PADMINUS, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_view_zoomin", PADPLUSKEY, KM_PRESS, 0, 0); /* zoom - drag */ - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); /* scrollers */ - WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "ED_View2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index da26b3dc297..e78beec3488 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1327,14 +1327,16 @@ void ED_operatortypes_screen(void) /* called in spacetypes.c */ void ED_keymap_screen(wmWindowManager *wm) { - WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_cursor_type", MOUSEMOVE, 0, 0, 0); - WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0); + ListBase *keymap= WM_keymap_listbase(wm, "Screen", 0, 0); - 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->screenkeymap, "ED_SCR_OT_area_rip", RKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_verify_item(keymap, "ED_SCR_OT_cursor_type", MOUSEMOVE, 0, 0, 0); + WM_keymap_verify_item(keymap, "ED_SCR_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0); + + WM_keymap_verify_item(keymap, "ED_SCR_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "ED_SCR_OT_area_split", EVT_ACTIONZONE, 0, 0, 0); /* action tria */ + WM_keymap_verify_item(keymap, "ED_SCR_OT_area_join", EVT_ACTIONZONE, 0, 0, 0); /* action tria */ + WM_keymap_verify_item(keymap, "ED_SCR_OT_area_rip", RKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_repeat_last", F4KEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "ED_SCR_OT_repeat_last", F4KEY, KM_PRESS, 0, 0); } diff --git a/source/blender/editors/screen/spacetypes.c b/source/blender/editors/screen/spacetypes.c index a74b3a20e4e..bafb8aef94f 100644 --- a/source/blender/editors/screen/spacetypes.c +++ b/source/blender/editors/screen/spacetypes.c @@ -43,8 +43,20 @@ #include "screen_intern.h" /* own module include */ +ARegionType *ED_regiontype_from_id(SpaceType *st, int regionid) +{ + ARegionType *art; + + for(art= st->regiontypes.first; art; art= art->next) + if(art->regionid==regionid) + return art; + + printf("Error, region type missing in %s\n", st->name); + return st->regiontypes.first; +} -/* only call once on startup, storage is static data (no malloc!) in kernel listbase */ + +/* only call once on startup, storage is global in BKE kernel listbase */ void ED_spacetypes_init(void) { const ListBase *spacetypes; @@ -59,13 +71,17 @@ void ED_spacetypes_init(void) /* register operator types for screen and all spaces */ ED_operatortypes_screen(); - + ui_operatortypes(); + ui_view2d_operatortypes(); + spacetypes = BKE_spacetypes_list(); for(type=spacetypes->first; type; type=type->next) type->operatortypes(); } /* called in wm.c */ +/* keymap definitions are registered only once per WM initialize, usually on file read, + using the keymap the actual areas/regions add the handlers */ void ED_spacetypes_keymap(wmWindowManager *wm) { const ListBase *spacetypes; diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 07f6253feb3..399a7f08205 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -52,6 +52,7 @@ #include "BKE_utildefines.h" #include "ED_area.h" +#include "ED_screen.h" #include "WM_api.h" #include "WM_types.h" @@ -496,37 +497,27 @@ static void outliner_init(wmWindowManager *wm, ScrArea *sa) ARegion *ar; /* link area to SpaceXXX struct */ + sa->type= BKE_spacetype_from_id(SPACE_OOPS); /* add handlers to area */ /* define how many regions, the order and types */ - /* add types to regions */ + /* add types to regions, check handlers */ for(ar= sa->regionbase.first; ar; ar= ar->next) { - if(ar->regiontype == RGN_TYPE_WINDOW) { - static ARegionType mainart={NULL, NULL, NULL, NULL, NULL}; + + ar->type= ED_regiontype_from_id(sa->type, ar->regiontype); /* XXX fix type and id */ + + if(ar->handlers.first==NULL) { + ListBase *keymap; + + /* XXX fixme, should be smarter */ + + keymap= WM_keymap_listbase(wm, "Interface", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_listbase(wm, "View2D", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); - mainart.draw= outliner_main_area_draw; - mainart.free= outliner_main_area_free; - - ar->type= &mainart; - - WM_event_add_keymap_handler(&ar->handlers, &wm->uikeymap); - WM_event_add_keymap_handler(&ar->handlers, &wm->view2dkeymap); - } - else if(ar->regiontype == RGN_TYPE_HEADER) { - static ARegionType headerart={NULL, NULL, NULL, NULL, NULL}; - - headerart.draw= outliner_header_area_draw; - headerart.free= outliner_header_area_free; - - ar->type= &headerart; - - WM_event_add_keymap_handler(&ar->handlers, &wm->uikeymap); - WM_event_add_keymap_handler(&ar->handlers, &wm->view2dkeymap); - } - else { - static ARegionType headerart={NULL, NULL, NULL, NULL, NULL}; - ar->type= &headerart; } } } @@ -551,18 +542,37 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl) /* only called once, from screen/spacetypes.c */ void ED_spacetype_outliner(void) { - static SpaceType st; + SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype time"); + ARegionType *art; + + st->spaceid= SPACE_OOPS; + strncpy(st->name, "Outliner", BKE_ST_MAXNAME); + + st->new= outliner_new; + st->free= outliner_free; + st->init= outliner_init; + st->refresh= outliner_refresh; + st->duplicate= outliner_duplicate; + st->operatortypes= outliner_operatortypes; + st->keymap= outliner_keymap; + + /* regions: main window */ + art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); + art->regionid = RGN_TYPE_WINDOW; + + art->draw= outliner_main_area_draw; + art->free= outliner_main_area_free; + BLI_addhead(&st->regiontypes, art); + + /* regions: header */ + art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); + art->regionid = RGN_TYPE_HEADER; - st.spaceid= SPACE_OOPS; + art->draw= outliner_header_area_draw; + art->free= outliner_header_area_free; + BLI_addhead(&st->regiontypes, art); - st.new= outliner_new; - st.free= outliner_free; - st.init= outliner_init; - st.refresh= outliner_refresh; - st.duplicate= outliner_duplicate; - st.operatortypes= outliner_operatortypes; - st.keymap= outliner_keymap; - BKE_spacetype_register(&st); + BKE_spacetype_register(st); } diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index bb9a99ec577..29b3b4559cb 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -36,10 +36,13 @@ #include "MEM_guardedalloc.h" +#include "BLI_blenlib.h" + #include "BKE_global.h" #include "BKE_screen.h" #include "ED_area.h" +#include "ED_screen.h" #include "WM_api.h" #include "WM_types.h" @@ -226,52 +229,38 @@ static void time_free(SpaceLink *sl) { } + /* spacetype; init callback */ +/* init is called to (re)initialize an existing editor (file read, screen changes) */ static void time_init(wmWindowManager *wm, ScrArea *sa) { ARegion *ar; /* link area to SpaceXXX struct */ + sa->type= BKE_spacetype_from_id(SPACE_TIME); /* add handlers to area */ /* define how many regions, the order and types */ - /* add types to regions */ + /* add types to regions, check handlers */ for(ar= sa->regionbase.first; ar; ar= ar->next) { - if(ar->regiontype == RGN_TYPE_WINDOW) { - static ARegionType mainart={NULL, NULL, NULL, NULL, NULL}; - - mainart.init= time_main_area_init; - mainart.refresh= time_main_area_refresh; - mainart.draw= time_main_area_draw; - mainart.listener= time_main_area_listener; - - ar->type= &mainart; - - /* XXX the windowmanager may not be the best place to keep these - * keymaps, and this function callback may not be the best one - * to add the keymap handler, also will need to take care of - * area type changes, etc, basically space callbacks need to - * be looked at further */ - WM_event_remove_keymap_handler(&ar->handlers, &wm->timekeymap); - WM_event_add_keymap_handler(&ar->handlers, &wm->timekeymap); - WM_event_add_keymap_handler(&ar->handlers, &wm->view2dkeymap); // XXX this should be added automatically! - } - else if(ar->regiontype == RGN_TYPE_HEADER) { - static ARegionType headerart={NULL, NULL, NULL, NULL, NULL}; - - headerart.draw= time_header_area_draw; - headerart.free= time_header_area_free; - - ar->type= &headerart; - WM_event_add_keymap_handler(&ar->handlers, &wm->uikeymap); - WM_event_add_keymap_handler(&ar->handlers, &wm->view2dkeymap); // XXX this should be added automatically! - } - else { - static ARegionType art={NULL, NULL, NULL, NULL, NULL}; - - /* for time being; register 1 type */ - ar->type= &art; + + ar->type= ED_regiontype_from_id(sa->type, ar->regiontype); /* XXX fix type and id */ + + if(ar->handlers.first==NULL) { + ListBase *keymap; + + /* XXX fixme, should be smarter */ + + keymap= WM_keymap_listbase(wm, "Interface", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + /* own keymap */ + keymap= WM_keymap_listbase(wm, "TimeLine", sa->spacetype, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_listbase(wm, "View2D", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); } } } @@ -291,20 +280,42 @@ static SpaceLink *time_duplicate(SpaceLink *sl) } /* only called once, from screen/spacetypes.c */ +/* it defines all callbacks to maintain spaces */ void ED_spacetype_time(void) { - static SpaceType st; + SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype time"); + ARegionType *art; + + st->spaceid= SPACE_TIME; + strncpy(st->name, "Timeline", BKE_ST_MAXNAME); + + st->new= time_new; + st->free= time_free; + st->init= time_init; + st->refresh= time_refresh; + st->duplicate= time_duplicate; + st->operatortypes= time_operatortypes; + st->keymap= time_keymap; + + /* regions: main window */ + art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); + art->regionid = RGN_TYPE_WINDOW; + + art->init= time_main_area_init; + art->refresh= time_main_area_refresh; + art->draw= time_main_area_draw; + art->listener= time_main_area_listener; + BLI_addhead(&st->regiontypes, art); + + /* regions: header */ + art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); + art->regionid = RGN_TYPE_HEADER; - st.spaceid= SPACE_TIME; + art->draw= time_header_area_draw; + art->free= time_header_area_free; + BLI_addhead(&st->regiontypes, art); - st.new= time_new; - st.free= time_free; - st.init= time_init; - st.refresh= time_refresh; - st.duplicate= time_duplicate; - st.operatortypes= time_operatortypes; - st.keymap= time_keymap; - BKE_spacetype_register(&st); + BKE_spacetype_register(st); } diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c index 9b7af8b3f45..bc0ed1634da 100644 --- a/source/blender/editors/space_time/time_ops.c +++ b/source/blender/editors/space_time/time_ops.c @@ -213,24 +213,26 @@ void time_operatortypes(void) void time_keymap(wmWindowManager *wm) { - WM_keymap_verify_item(&wm->timekeymap, "ED_TIME_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(&wm->timekeymap, "ED_TIME_OT_toggle_time", TKEY, KM_PRESS, 0, 0); + ListBase *keymap= WM_keymap_listbase(wm, "TimeLine", SPACE_TIME, 0); + + WM_keymap_verify_item(keymap, "ED_TIME_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "ED_TIME_OT_toggle_time", TKEY, KM_PRESS, 0, 0); /* markers (XXX move to function?) */ - WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_add", MKEY, KM_PRESS, 0, 0); - WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_move", EVT_TWEAK_R, KM_ANY, 0, 0); - WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_mouseselect", RIGHTMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_mouseselect_extend", RIGHTMOUSE, KM_PRESS, KM_SHIFT, 0); - WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_border_select", BKEY, KM_PRESS, 0, 0); - WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0); - WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "ED_MARKER_OT_add", MKEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "ED_MARKER_OT_move", EVT_TWEAK_R, KM_ANY, 0, 0); + WM_keymap_verify_item(keymap, "ED_MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_verify_item(keymap, "ED_MARKER_OT_mouseselect", RIGHTMOUSE, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "ED_MARKER_OT_mouseselect_extend", RIGHTMOUSE, KM_PRESS, KM_SHIFT, 0); + WM_keymap_verify_item(keymap, "ED_MARKER_OT_border_select", BKEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "ED_MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "ED_MARKER_OT_delete", XKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(&wm->timekeymap, "ED_MARKER_OT_move", GKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "ED_MARKER_OT_move", GKEY, KM_PRESS, 0, 0); /* generates event, in end to make select work */ - WM_keymap_verify_item(&wm->timekeymap, "WM_OT_tweak_gesture", RIGHTMOUSE, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "WM_OT_tweak_gesture", RIGHTMOUSE, KM_PRESS, 0, 0); } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index d60dd6a4062..81911a510ae 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -185,18 +185,18 @@ void view3d_keymap(struct wmWindowManager *wm) /* only called once, from screen/spacetypes.c */ void ED_spacetype_view3d(void) { - static SpaceType st; + SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype time"); - st.spaceid= SPACE_VIEW3D; + st->spaceid= SPACE_VIEW3D; - st.new= view3d_new; - st.free= view3d_free; - st.init= view3d_init; - st.refresh= view3d_refresh; - st.duplicate= view3d_duplicate; - st.operatortypes= view3d_operatortypes; - st.keymap= view3d_keymap; + st->new= view3d_new; + st->free= view3d_free; + st->init= view3d_init; + st->refresh= view3d_refresh; + st->duplicate= view3d_duplicate; + st->operatortypes= view3d_operatortypes; + st->keymap= view3d_keymap; - BKE_spacetype_register(&st); + BKE_spacetype_register(st); } diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index c67a482ccaa..867007032b6 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -66,13 +66,8 @@ typedef struct wmWindowManager { ListBase reports; /* information and error reports */ - /* custom keymaps */ - ListBase windowkeymap; - ListBase screenkeymap; - ListBase view2dkeymap; - ListBase uikeymap; - ListBase timekeymap; - /* keymaps have to be NULLed in readfile.c */ + /* used keymaps, optionally/partially saved */ + ListBase keymaps; } wmWindowManager; @@ -157,6 +152,19 @@ typedef struct wmKeymapItem { short pad; } wmKeymapItem; +#define KMAP_MAX_NAME 64 + +/* stored in WM, the actively used keymaps */ +typedef struct wmKeyMap { + struct wmKeyMap *next, *prev; + + 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 */ +} wmKeyMap; + /* this one is the operator itself, stored in files for macros etc */ /* operator + operatortype should be able to redo entirely, but for different contextes */ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 7bbb97d9c42..9dbb4c46947 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -67,6 +67,10 @@ void WM_keymap_verify_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier); void WM_keymap_add_item (ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier); +ListBase *WM_keymap_listbase (wmWindowManager *wm, const char *nameid, + int spaceid, int regionid); + + struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap); void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 7c1532210d9..3333c485aae 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -136,6 +136,7 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm) wmWindow *win; wmOperator *op; wmReport *report; + wmKeyMap *km; while((win= wm->windows.first)) { BLI_remlink(&wm->windows, win); @@ -152,11 +153,11 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm) wm_report_free(report); } - BLI_freelistN(&wm->timekeymap); - BLI_freelistN(&wm->view2dkeymap); - BLI_freelistN(&wm->uikeymap); - BLI_freelistN(&wm->windowkeymap); - BLI_freelistN(&wm->screenkeymap); + while((km= wm->keymaps.first)) { + BLI_freelistN(&km->keymap); + BLI_remlink(&wm->keymaps, km); + MEM_freeN(km); + } BLI_freelistN(&wm->queue); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ac153b76c7e..c74497fa10b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -347,20 +347,20 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) } } -static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *km) +static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi) { - if(winevent->type!=km->type) return 0; + if(winevent->type!=kmi->type) return 0; - if(km->val!=KM_ANY) - if(winevent->val!=km->val) return 0; + if(kmi->val!=KM_ANY) + if(winevent->val!=kmi->val) return 0; - if(winevent->shift!=km->shift) return 0; - if(winevent->ctrl!=km->ctrl) return 0; - if(winevent->alt!=km->alt) return 0; - if(winevent->oskey!=km->oskey) return 0; - if(km->keymodifier) - if(winevent->keymodifier!=km->keymodifier) return 0; + if(winevent->shift!=kmi->shift) return 0; + if(winevent->ctrl!=kmi->ctrl) return 0; + if(winevent->alt!=kmi->alt) return 0; + if(winevent->oskey!=kmi->oskey) return 0; + if(kmi->keymodifier) + if(winevent->keymodifier!=kmi->keymodifier) return 0; /* optional boundbox */ @@ -449,14 +449,14 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) action= WM_HANDLER_BREAK; if(handler->keymap) { - wmKeymapItem *km; + wmKeymapItem *kmi; - for(km= handler->keymap->first; km; km= km->next) { - if(wm_eventmatch(event, km)) { + for(kmi= handler->keymap->first; kmi; kmi= kmi->next) { + if(wm_eventmatch(event, kmi)) { /* if(event->type!=MOUSEMOVE) - printf("handle evt %d win %d op %s\n", event->type, C->window->winid, km->idname); */ + printf("handle evt %d win %d op %s\n", event->type, C->window->winid, kmi->idname); */ - event->keymap_idname= km->idname; /* weak, but allows interactive callback to not use rawkey */ + event->keymap_idname= kmi->idname; /* weak, but allows interactive callback to not use rawkey */ action= wm_handler_operator_call(C, handlers, handler, event); if(action==WM_HANDLER_BREAK) /* not wm_event_always_pass(event) here, it denotes removed handler */ diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 610222b4372..439f5c304d1 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -47,45 +47,45 @@ /* ***************** generic call, exported **************** */ -static void keymap_set(wmKeymapItem *km, short type, short val, int modifier, short keymodifier) +static void keymap_set(wmKeymapItem *kmi, short type, short val, int modifier, short keymodifier) { - km->type= type; - km->val= val; - km->keymodifier= keymodifier; + kmi->type= type; + kmi->val= val; + kmi->keymodifier= keymodifier; if(modifier & KM_SHIFT) - km->shift= 1; + kmi->shift= 1; else if(modifier & KM_SHIFT2) - km->shift= 2; + kmi->shift= 2; if(modifier & KM_CTRL) - km->ctrl= 1; + kmi->ctrl= 1; else if(modifier & KM_CTRL2) - km->ctrl= 2; + kmi->ctrl= 2; if(modifier & KM_ALT) - km->alt= 1; + kmi->alt= 1; else if(modifier & KM_ALT2) - km->alt= 2; + kmi->alt= 2; if(modifier & KM_OSKEY) - km->oskey= 1; + kmi->oskey= 1; else if(modifier & KM_OSKEY2) - km->oskey= 2; + kmi->oskey= 2; } /* 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; + wmKeymapItem *kmi; - for(km= lb->first; km; km= km->next) - if(strncmp(km->idname, idname, OP_MAX_TYPENAME)==0) + for(kmi= lb->first; kmi; kmi= kmi->next) + if(strncmp(kmi->idname, idname, OP_MAX_TYPENAME)==0) break; - if(km==NULL) { - km= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); + if(kmi==NULL) { + kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); - BLI_addtail(lb, km); - BLI_strncpy(km->idname, idname, OP_MAX_TYPENAME); + BLI_addtail(lb, kmi); + BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); - keymap_set(km, type, val, modifier, keymodifier); + keymap_set(kmi, type, val, modifier, keymodifier); } } @@ -93,30 +93,55 @@ void WM_keymap_verify_item(ListBase *lb, char *idname, short type, short val, in /* if item was added, then replace */ void WM_keymap_set_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier) { - wmKeymapItem *km; + wmKeymapItem *kmi; - for(km= lb->first; km; km= km->next) - if(strncmp(km->idname, idname, OP_MAX_TYPENAME)==0) + for(kmi= lb->first; kmi; kmi= kmi->next) + if(strncmp(kmi->idname, idname, OP_MAX_TYPENAME)==0) break; - if(km==NULL) { - km= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); + if(kmi==NULL) { + kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); - BLI_addtail(lb, km); - BLI_strncpy(km->idname, idname, OP_MAX_TYPENAME); + BLI_addtail(lb, kmi); + BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); } - keymap_set(km, type, val, modifier, keymodifier); + keymap_set(kmi, type, val, modifier, keymodifier); } /* always add item */ void WM_keymap_add_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier) { - wmKeymapItem *km= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); + wmKeymapItem *kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); - BLI_addtail(lb, km); - BLI_strncpy(km->idname, idname, OP_MAX_TYPENAME); + BLI_addtail(lb, kmi); + BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); - keymap_set(km, type, val, modifier, keymodifier); + keymap_set(kmi, type, val, modifier, keymodifier); } +/* ****************** storage in WM ************ */ + +/* name id's are for storing general or multiple keymaps, + 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) +{ + wmKeyMap *km; + + for(km= wm->keymaps.first; km; km= km->next) + 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); + km->spaceid= spaceid; + km->regionid= regionid; + printf("added keymap %s %d %d\n", nameid, spaceid, regionid); + BLI_addtail(&wm->keymaps, km); + } + + return &km->keymap; +} diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 17b248ae9ed..5dd36d737b1 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -352,10 +352,12 @@ void wm_operatortype_init(void) /* default keymap for windows and screens, only call once per WM */ void wm_window_keymap(wmWindowManager *wm) { + ListBase *keymap= WM_keymap_listbase(wm, "Window", 0, 0); + /* note, this doesn't replace existing keymap items */ - WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_window_duplicate", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); - WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0); - WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); + WM_keymap_verify_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 884abc1fa25..508fe21b039 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -190,6 +190,7 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, char *title, wmWindow 0 /* no stereo */); if (ghostwin) { + ListBase *keymap; win->ghostwin= ghostwin; GHOST_SetWindowUserData(ghostwin, win); /* pointer back */ @@ -197,9 +198,12 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, char *title, wmWindow if(win->eventstate==NULL) win->eventstate= MEM_callocN(sizeof(wmEvent), "window event state"); - /* add keymap handlers (1 for all keys in map!) */ - WM_event_add_keymap_handler(&win->handlers, &wm->windowkeymap); - WM_event_add_keymap_handler(&win->handlers, &wm->screenkeymap); + /* add keymap handlers (1 handler for all keys in map!) */ + keymap= WM_keymap_listbase(wm, "Window", 0, 0); + WM_event_add_keymap_handler(&win->handlers, keymap); + + keymap= WM_keymap_listbase(wm, "Screen", 0, 0); + WM_event_add_keymap_handler(&win->handlers, keymap); /* until screens get drawn, make it nice grey */ glClearColor(.55, .55, .55, 0.0); diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 1b3b7ce8efb..0c37c56778f 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -66,11 +66,12 @@ enum { }; +/* wm_event_system.c */ void wm_event_add(wmWindow *win, wmEvent *event_to_add); void wm_event_free_all (wmWindow *win); wmEvent *wm_event_next (wmWindow *win); -/* goes over entire hierarchy: events -> window -> screen -> area -> region */ + /* goes over entire hierarchy: events -> window -> screen -> area -> region */ void wm_event_do_handlers (bContext *C); void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata); @@ -78,5 +79,8 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata); void wm_event_do_notifiers (bContext *C); void wm_draw_update (bContext *C); +/* wm_keymap.c */ + + #endif /* WM_EVENT_SYSTEM_H */ |