diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_event_system.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 106 |
1 files changed, 103 insertions, 3 deletions
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 15b155c8649..8b4fdfb3021 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1455,6 +1455,40 @@ static void wm_handler_op_context(bContext *C, wmEventHandler *handler, const wm } } +static void wm_handler_widgetmap_context(bContext *C, wmEventHandler *handler) +{ + bScreen *screen = CTX_wm_screen(C); + + if (screen) { + if (handler->op_area == NULL) { + /* do nothing in this context */ + } + else { + ScrArea *sa; + + for (sa = screen->areabase.first; sa; sa = sa->next) + if (sa == handler->op_area) + break; + if (sa == NULL) { + /* when changing screen layouts with running modal handlers (like render display), this + * is not an error to print */ + if (handler->widgetmap == NULL) + printf("internal error: modal widgetmap handler has invalid area\n"); + } + else { + ARegion *ar; + CTX_wm_area_set(C, sa); + for (ar = sa->regionbase.first; ar; ar = ar->next) + if (ar == handler->op_region) + break; + /* XXX no warning print here, after full-area and back regions are remade */ + if (ar) + CTX_wm_region_set(C, ar); + } + } + } +} + /* called on exit or remove area, only here call cancel callback */ void WM_event_remove_handlers(bContext *C, ListBase *handlers) { @@ -1478,7 +1512,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) if (handler->op->type->flag & OPTYPE_UNDO) wm->op_undo_depth--; - + CTX_wm_area_set(C, area); CTX_wm_region_set(C, region); } @@ -1665,8 +1699,8 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand /* warning, after this call all context data and 'event' may be freed. see check below */ retval = ot->modal(C, op, event); + OPERATOR_RETVAL_CHECK(retval); - /* when this is _not_ the case the modal modifier may have loaded * a new blend file (demo mode does this), so we have to assume * the event, operator etc have all been freed. - campbell */ @@ -2060,7 +2094,72 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers } } } + else if (handler->widgetmap) { + struct wmWidgetMap *wmap = handler->widgetmap; + unsigned char part; + short event_processed = 0; + wmWidget *widget = wm_widgetmap_get_active_widget(wmap); + ScrArea *area = CTX_wm_area(C); + ARegion *region = CTX_wm_region(C); + + wm_handler_widgetmap_context(C, handler); + wm_region_mouse_co(C, event); + + switch (event->type) { + case MOUSEMOVE: + if (widget) { + widget->handler(C, event, widget); + event_processed = EVT_WIDGET_UPDATE; + action |= WM_HANDLER_BREAK; + } + else if (wm_widgetmap_is_3d(wmap)) { + widget = wm_widget_find_highlighted_3D(wmap, C, event, &part); + wm_widgetmap_set_highlighted_widget(wmap, C, widget, part); + } + else { + widget = wm_widget_find_highlighted(wmap, C, event, &part); + wm_widgetmap_set_highlighted_widget(wmap, C, widget, part); + } + break; + + case LEFTMOUSE: + { + if (widget) { + if (event->val == KM_RELEASE) { + wm_widgetmap_set_active_widget(wmap, C, event, NULL, false); + event_processed = EVT_WIDGET_RELEASED; + action |= WM_HANDLER_BREAK; + } + else { + action |= WM_HANDLER_BREAK; + } + } + else if (event->val == KM_PRESS) { + widget = wm_widgetmap_get_highlighted_widget(wmap); + + if (widget) { + wm_widgetmap_set_active_widget(wmap, C, event, widget, handler->op == NULL); + action |= WM_HANDLER_BREAK; + } + } + break; + } + } + + /* restore the area */ + CTX_wm_area_set(C, area); + CTX_wm_region_set(C, region); + + if (handler->op) { + /* if event was processed by an active widget pass the modified event to the operator */ + if (event_processed) { + event->type = event_processed; + } + action |= wm_handler_operator_call(C, handlers, handler, event, NULL); + } + } else { + /* handle the widget first, before passing the event down */ /* modal, swallows all */ action |= wm_handler_operator_call(C, handlers, handler, event, NULL); } @@ -2613,7 +2712,7 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op) { wmEventHandler *handler = MEM_callocN(sizeof(wmEventHandler), "event modal handler"); wmWindow *win = CTX_wm_window(C); - + /* operator was part of macro */ if (op->opm) { /* give the mother macro to the handler */ @@ -3578,6 +3677,7 @@ void WM_event_ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4]) angle = WM_event_ndof_to_axis_angle(ndof, axis); axis_angle_to_quat(q, axis, angle); } +/** \} */ /* if this is a tablet event, return tablet pressure and set *pen_flip * to 1 if the eraser tool is being used, 0 otherwise */ |