diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-02-19 05:57:11 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-02-19 08:17:21 +0300 |
commit | eae2942474fa06b369b3fc6ebdeddad90ca38d43 (patch) | |
tree | 9f86fe5ccf647da525906186f617171c0e6aadeb /source/blender/windowmanager | |
parent | 55ac296358a45fd11700df328fb47f061c8aca4f (diff) |
WM: move UI handler to it's own type
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 205 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_system.h | 24 |
2 files changed, 136 insertions, 93 deletions
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index d40a9be9e9e..c47247b794d 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -543,7 +543,7 @@ static int wm_event_always_pass(const wmEvent *event) /* ********************* ui handler ******************* */ -static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, const wmEvent *event, int always_pass) +static int wm_handler_ui_call(bContext *C, wmEventHandler_UI *handler, const wmEvent *event, int always_pass) { ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); @@ -554,7 +554,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, const wmEven /* UI code doesn't handle return values - it just always returns break. * to make the DBL_CLICK conversion work, we just don't send this to UI, except mouse clicks */ - if (((handler->flag & WM_HANDLER_ACCEPT_DBL_CLICK) == 0) && + if (((handler->base.flag & WM_HANDLER_ACCEPT_DBL_CLICK) == 0) && !ISMOUSE_BUTTON(event->type) && (event->val == KM_DBL_CLICK)) { @@ -571,11 +571,17 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, const wmEven } /* we set context to where ui handler came from */ - if (handler->ui_area) CTX_wm_area_set(C, handler->ui_area); - if (handler->ui_region) CTX_wm_region_set(C, handler->ui_region); - if (handler->ui_menu) CTX_wm_menu_set(C, handler->ui_menu); + if (handler->context.area) { + CTX_wm_area_set(C, handler->context.area); + } + if (handler->context.region) { + CTX_wm_region_set(C, handler->context.region); + } + if (handler->context.menu) { + CTX_wm_menu_set(C, handler->context.menu); + } - retval = handler->ui_handle(C, event, handler->ui_userdata); + retval = handler->handle_fn(C, event, handler->user_data); /* putting back screen context */ if ((retval != WM_UI_HANDLER_BREAK) || always_pass) { @@ -604,20 +610,22 @@ static void wm_handler_ui_cancel(bContext *C) { wmWindow *win = CTX_wm_window(C); ARegion *ar = CTX_wm_region(C); - wmEventHandler *handler, *nexthandler; if (!ar) return; - for (handler = ar->handlers.first; handler; handler = nexthandler) { - nexthandler = handler->next; - - if (handler->ui_handle) { + for (wmEventHandler *handler_base = ar->handlers.first, *handler_base_next; + handler_base; + handler_base = handler_base_next) + { + handler_base_next = handler_base->next; + if (handler_base->type == WM_HANDLER_TYPE_UI) { + wmEventHandler_UI *handler = (wmEventHandler_UI *)handler_base; + BLI_assert(handler->handle_fn != NULL); wmEvent event; - wm_event_init_from_window(win, &event); event.type = EVT_BUT_CANCEL; - handler->ui_handle(C, &event, handler->ui_userdata); + handler->handle_fn(C, &event, handler->user_data); } } } @@ -1732,25 +1740,25 @@ static void wm_handler_op_context(bContext *C, wmEventHandler *handler, const wm /* called on exit or remove area, only here call cancel callback */ void WM_event_remove_handlers(bContext *C, ListBase *handlers) { - wmEventHandler *handler; + wmEventHandler *handler_base; wmWindowManager *wm = CTX_wm_manager(C); /* C is zero on freeing database, modal handlers then already were freed */ - while ((handler = BLI_pophead(handlers))) { - if (handler->op) { + while ((handler_base = BLI_pophead(handlers))) { + if (handler_base->op) { wmWindow *win = CTX_wm_window(C); - if (handler->op->type->cancel) { + if (handler_base->op->type->cancel) { ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - wm_handler_op_context(C, handler, win->eventstate); + wm_handler_op_context(C, handler_base, win->eventstate); - if (handler->op->type->flag & OPTYPE_UNDO) + if (handler_base->op->type->flag & OPTYPE_UNDO) wm->op_undo_depth++; - handler->op->type->cancel(C, handler->op); + handler_base->op->type->cancel(C, handler_base->op); - if (handler->op->type->flag & OPTYPE_UNDO) + if (handler_base->op->type->flag & OPTYPE_UNDO) wm->op_undo_depth--; CTX_wm_area_set(C, area); @@ -1758,25 +1766,35 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) } WM_cursor_grab_disable(win, NULL); - WM_operator_free(handler->op); + WM_operator_free(handler_base->op); } - else if (handler->ui_remove) { - ScrArea *area = CTX_wm_area(C); - ARegion *region = CTX_wm_region(C); - ARegion *menu = CTX_wm_menu(C); + else if (handler_base->type == WM_HANDLER_TYPE_UI) { + wmEventHandler_UI *handler = (wmEventHandler_UI *)handler_base; - if (handler->ui_area) CTX_wm_area_set(C, handler->ui_area); - if (handler->ui_region) CTX_wm_region_set(C, handler->ui_region); - if (handler->ui_menu) CTX_wm_menu_set(C, handler->ui_menu); + if (handler->remove_fn) { + ScrArea *area = CTX_wm_area(C); + ARegion *region = CTX_wm_region(C); + ARegion *menu = CTX_wm_menu(C); - handler->ui_remove(C, handler->ui_userdata); + if (handler->context.area) { + CTX_wm_area_set(C, handler->context.area); + } + if (handler->context.region) { + CTX_wm_region_set(C, handler->context.region); + } + if (handler->context.menu) { + CTX_wm_menu_set(C, handler->context.menu); + } + + handler->remove_fn(C, handler->user_data); - CTX_wm_area_set(C, area); - CTX_wm_region_set(C, region); - CTX_wm_menu_set(C, menu); + CTX_wm_area_set(C, area); + CTX_wm_region_set(C, region); + CTX_wm_menu_set(C, menu); + } } - wm_event_free_handler(handler); + wm_event_free_handler(handler_base); } } @@ -2388,9 +2406,11 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers PRINT("fail\n"); } } - else if (handler->ui_handle) { + else if (handler->type == WM_HANDLER_TYPE_UI) { + wmEventHandler_UI *handler_ui = (wmEventHandler_UI *)handler; + BLI_assert(handler_ui->handle_fn != NULL); if (!wm->is_interface_locked) { - action |= wm_handler_ui_call(C, handler, event, always_pass); + action |= wm_handler_ui_call(C, handler_ui, event, always_pass); } } else if (handler->op_is_fileselect) { @@ -3399,72 +3419,80 @@ void WM_event_set_keymap_handler_callback( wmEventHandler *WM_event_add_ui_handler( const bContext *C, ListBase *handlers, - wmUIHandlerFunc ui_handle, wmUIHandlerRemoveFunc ui_remove, - void *userdata, const char flag) + wmUIHandlerFunc handle_fn, wmUIHandlerRemoveFunc remove_fn, + void *user_data, const char flag) { - wmEventHandler *handler = MEM_callocN(sizeof(wmEventHandler), "event ui handler"); - handler->ui_handle = ui_handle; - handler->ui_remove = ui_remove; - handler->ui_userdata = userdata; + wmEventHandler_UI *handler = MEM_callocN(sizeof(*handler), __func__); + handler->base.type = WM_HANDLER_TYPE_UI; + handler->handle_fn = handle_fn; + handler->remove_fn = remove_fn; + handler->user_data = user_data; if (C) { - handler->ui_area = CTX_wm_area(C); - handler->ui_region = CTX_wm_region(C); - handler->ui_menu = CTX_wm_menu(C); + handler->context.area = CTX_wm_area(C); + handler->context.region = CTX_wm_region(C); + handler->context.menu = CTX_wm_menu(C); } else { - handler->ui_area = NULL; - handler->ui_region = NULL; - handler->ui_menu = NULL; + handler->context.area = NULL; + handler->context.region = NULL; + handler->context.menu = NULL; } BLI_assert((flag & WM_HANDLER_DO_FREE) == 0); - handler->flag = flag; + handler->base.flag = flag; BLI_addhead(handlers, handler); - return handler; + return &handler->base; } /* set "postpone" for win->modalhandlers, this is in a running for () loop in wm_handlers_do() */ void WM_event_remove_ui_handler( ListBase *handlers, - wmUIHandlerFunc ui_handle, wmUIHandlerRemoveFunc ui_remove, - void *userdata, const bool postpone) + wmUIHandlerFunc handle_fn, wmUIHandlerRemoveFunc remove_fn, + void *user_data, const bool postpone) { - wmEventHandler *handler; - - for (handler = handlers->first; handler; handler = handler->next) { - if ((handler->ui_handle == ui_handle) && - (handler->ui_remove == ui_remove) && - (handler->ui_userdata == userdata)) - { - /* handlers will be freed in wm_handlers_do() */ - if (postpone) { - handler->flag |= WM_HANDLER_DO_FREE; - } - else { - BLI_remlink(handlers, handler); - wm_event_free_handler(handler); + wmEventHandler *handler_base; + + for (handler_base = handlers->first; handler_base; handler_base = handler_base->next) { + if (handler_base->type == WM_HANDLER_TYPE_UI) { + wmEventHandler_UI *handler = (wmEventHandler_UI *)handler_base; + if ((handler->handle_fn == handle_fn) && + (handler->remove_fn == remove_fn) && + (handler->user_data == user_data)) + { + /* handlers will be freed in wm_handlers_do() */ + if (postpone) { + handler->base.flag |= WM_HANDLER_DO_FREE; + } + else { + BLI_remlink(handlers, handler); + wm_event_free_handler(&handler->base); + } + break; } - break; } } } void WM_event_free_ui_handler_all( bContext *C, ListBase *handlers, - wmUIHandlerFunc ui_handle, wmUIHandlerRemoveFunc ui_remove) + wmUIHandlerFunc handle_fn, wmUIHandlerRemoveFunc remove_fn) { - wmEventHandler *handler, *handler_next; - - for (handler = handlers->first; handler; handler = handler_next) { - handler_next = handler->next; - if ((handler->ui_handle == ui_handle) && - (handler->ui_remove == ui_remove)) - { - ui_remove(C, handler->ui_userdata); - BLI_remlink(handlers, handler); - wm_event_free_handler(handler); + for (wmEventHandler *handler_base = handlers->first, *handler_base_next; + handler_base; + handler_base = handler_base_next) + { + handler_base_next = handler_base->next; + if (handler_base->type == WM_HANDLER_TYPE_UI) { + wmEventHandler_UI *handler = (wmEventHandler_UI *)handler_base; + if ((handler->handle_fn == handle_fn) && + (handler->remove_fn == remove_fn)) + { + remove_fn(C, handler->user_data); + BLI_remlink(handlers, handler); + wm_event_free_handler(&handler->base); + } } } } @@ -3490,14 +3518,17 @@ wmEventHandler *WM_event_add_dropbox_handler(ListBase *handlers, ListBase *dropb /* XXX solution works, still better check the real cause (ton) */ void WM_event_remove_area_handler(ListBase *handlers, void *area) { - wmEventHandler *handler, *nexthandler; - for (handler = handlers->first; handler; handler = nexthandler) { - nexthandler = handler->next; - if (handler->op_is_fileselect == false) { - if (handler->ui_area == area) { + for (wmEventHandler *handler_base = handlers->first, *handler_base_next; + handler_base; + handler_base = handler_base_next) + { + handler_base_next = handler_base->next; + if (handler_base->type == WM_HANDLER_TYPE_UI) { + wmEventHandler_UI *handler = (wmEventHandler_UI *)handler_base; + if (handler->context.area == area) { BLI_remlink(handlers, handler); - wm_event_free_handler(handler); + wm_event_free_handler(handler_base); } } } @@ -3843,9 +3874,11 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi /* let's skip windows having modal handlers now */ /* potential XXX ugly... I wouldn't have added a modalhandlers list (introduced in rev 23331, ton) */ - for (handler = win->modalhandlers.first; handler; handler = handler->next) - if (handler->ui_handle || handler->op) + for (handler = win->modalhandlers.first; handler; handler = handler->next) { + if ((handler->type == WM_HANDLER_TYPE_UI) || handler->op) { return NULL; + } + } /* to desktop space */ mx += (int) (U.pixelsize * win->posx); diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index e585d40ebb9..3e9793521ae 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -44,6 +44,7 @@ struct wmEventHandler_KeymapFn { enum eWM_EventHandlerType { WM_HANDLER_TYPE_DEFAULT, WM_HANDLER_TYPE_GIZMO, + WM_HANDLER_TYPE_UI, }; typedef struct wmEventHandler { @@ -67,13 +68,6 @@ typedef struct wmEventHandler { struct ARegion *op_region; /* for derived/modal handlers */ short op_region_type; /* for derived/modal handlers */ - /* ui handler */ - wmUIHandlerFunc ui_handle; /* callback receiving events */ - wmUIHandlerRemoveFunc ui_remove; /* callback when handler is removed */ - void *ui_userdata; /* user data pointer */ - struct ScrArea *ui_area; /* for derived/modal handlers */ - struct ARegion *ui_region; /* for derived/modal handlers */ - struct ARegion *ui_menu; /* for derived/modal handlers */ /* drop box handler */ ListBase *dropboxes; @@ -87,6 +81,22 @@ typedef struct wmEventHandler_Gizmo { struct wmGizmoMap *gizmo_map; } wmEventHandler_Gizmo; +/** #WM_HANDLER_TYPE_UI */ +typedef struct wmEventHandler_UI { + wmEventHandler base; + + wmUIHandlerFunc handle_fn; /* callback receiving events */ + wmUIHandlerRemoveFunc remove_fn; /* callback when handler is removed */ + void *user_data; /* user data pointer */ + + /** Store context for this handler for derived/modal handlers. */ + struct { + struct ScrArea *area; + struct ARegion *region; + struct ARegion *menu; + } context; +} wmEventHandler_UI; + /* wm_event_system.c */ void wm_event_free_all (wmWindow *win); void wm_event_free (wmEvent *event); |