Merge branch 'master' into blender2.8
[blender.git] / source / blender / windowmanager / intern / wm_event_system.c
index eba132062c912d3b0e50b3cd7e2e25561e4b591a..a2aca589f72239b6149744f09924c38019c9b071 100644 (file)
@@ -68,8 +68,6 @@
 
 #include "RNA_access.h"
 
-#include "GPU_debug.h"
-
 #include "UI_interface.h"
 
 #include "PIL_time.h"
@@ -1677,7 +1675,12 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
                        wm_handler_op_context(C, handler, event);
                        wm_region_mouse_co(C, event);
                        wm_event_modalkeymap(C, op, event, &dbl_click_disabled);
-                       
+
+                       /* attach manipulator-map to handler if not there yet */
+                       if (ot->mgrouptype && !handler->manipulator_map) {
+                               wm_manipulatorgroup_attach_to_modal_handler(C, handler, ot->mgrouptype, op);
+                       }
+
                        if (ot->flag & OPTYPE_UNDO)
                                wm->op_undo_depth++;
 
@@ -1726,6 +1729,9 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
                                        CTX_wm_region_set(C, NULL);
                                }
 
+                               /* update manipulators during modal handlers */
+                               wm_manipulatormaps_handled_modal_update(C, event, handler, ot);
+
                                /* remove modal handler, operator itself should have been canceled and freed */
                                if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) {
                                        WM_cursor_grab_disable(CTX_wm_window(C), NULL);
@@ -2098,6 +2104,71 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
                                        }
                                }
                        }
+                       else if (handler->manipulator_map) {
+                               ScrArea *area = CTX_wm_area(C);
+                               ARegion *region = CTX_wm_region(C);
+                               wmManipulatorMap *mmap = handler->manipulator_map;
+                               wmManipulator *manipulator = wm_manipulatormap_get_highlighted_manipulator(mmap);
+                               unsigned char part;
+
+                               wm_manipulatormap_handler_context(C, handler);
+                               wm_region_mouse_co(C, event);
+
+                               /* handle manipulator highlighting */
+                               if (event->type == MOUSEMOVE && !wm_manipulatormap_get_active_manipulator(mmap)) {
+                                       manipulator = wm_manipulatormap_find_highlighted_manipulator(mmap, C, event, &part);
+                                       wm_manipulatormap_set_highlighted_manipulator(mmap, C, manipulator, part);
+                               }
+                               /* handle user configurable manipulator-map keymap */
+                               else if (manipulator) {
+                                       /* get user customized keymap from default one */
+                                       const wmManipulatorGroup *highlightgroup = wm_manipulator_get_parent_group(manipulator);
+                                       const wmKeyMap *keymap = WM_keymap_active(wm, highlightgroup->type->keymap);
+                                       wmKeyMapItem *kmi;
+
+                                       PRINT("%s:   checking '%s' ...", __func__, keymap->idname);
+
+                                       if (!keymap->poll || keymap->poll(C)) {
+                                               PRINT("pass\n");
+                                               for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
+                                                       if (wm_eventmatch(event, kmi)) {
+                                                               wmOperator *op = handler->op;
+
+                                                               PRINT("%s:     item matched '%s'\n", __func__, kmi->idname);
+
+                                                               /* weak, but allows interactive callback to not use rawkey */
+                                                               event->keymap_idname = kmi->idname;
+
+                                                               /* handler->op is called later, we want keymap op to be triggered here */
+                                                               handler->op = NULL;
+                                                               action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr);
+                                                               handler->op = op;
+
+                                                               if (action & WM_HANDLER_BREAK) {
+                                                                       if (action & WM_HANDLER_HANDLED) {
+                                                                               if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS))
+                                                                                       printf("%s:       handled - and pass on! '%s'\n", __func__, kmi->idname);
+                                                                       }
+                                                                       else {
+                                                                               PRINT("%s:       un-handled '%s'\n", __func__, kmi->idname);
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       else {
+                                               PRINT("fail\n");
+                                       }
+                               }
+
+                               /* restore the area */
+                               CTX_wm_area_set(C, area);
+                               CTX_wm_region_set(C, region);
+
+                               if (handler->op) {
+                                       action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
+                               }
+                       }
                        else {
                                /* modal, swallows all */
                                action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
@@ -2540,8 +2611,6 @@ void wm_event_do_handlers(bContext *C)
 
        /* update key configuration after handling events */
        WM_keyconfig_update(wm);
-
-       GPU_ASSERT_NO_GL_ERRORS("wm_event_do_handlers");
 }
 
 /* ********** filesector handling ************ */
@@ -2578,7 +2647,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
        wmWindow *win = CTX_wm_window(C);
 
        /* only allow 1 file selector open per window */
-       for (handler = win->modalhandlers.first; handler; handler = handlernext) {
+       for (handler = win->handlers.first; handler; handler = handlernext) {
                handlernext = handler->next;
                
                if (handler->type == WM_HANDLER_FILESELECT) {
@@ -2592,7 +2661,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
 
                                        if (sfile->op == handler->op) {
                                                CTX_wm_area_set(C, sa);
-                                               wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_CANCEL);
+                                               wm_handler_fileselect_do(C, &win->handlers, handler, EVT_FILESELECT_CANCEL);
                                                break;
                                        }
                                }
@@ -2600,7 +2669,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
 
                        /* if not found we stop the handler without changing the screen */
                        if (!sa)
-                               wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_EXTERNAL_CANCEL);
+                               wm_handler_fileselect_do(C, &win->handlers, handler, EVT_FILESELECT_EXTERNAL_CANCEL);
                }
        }
        
@@ -2611,7 +2680,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
        handler->op_area = CTX_wm_area(C);
        handler->op_region = CTX_wm_region(C);
        
-       BLI_addhead(&win->modalhandlers, handler);
+       BLI_addhead(&win->handlers, handler);
        
        /* check props once before invoking if check is available
         * ensures initial properties are valid */
@@ -2654,6 +2723,33 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
        return handler;
 }
 
+/**
+ * Modal handlers store a pointer to an area which might be freed while the handler runs.
+ * Use this function to NULL all handler pointers to \a old_area.
+ */
+void WM_event_modal_handler_area_replace(wmWindow *win, const ScrArea *old_area, ScrArea *new_area)
+{
+       for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
+               if (handler->op_area == old_area) {
+                       handler->op_area = new_area;
+               }
+       }
+}
+
+/**
+ * Modal handlers store a pointer to a region which might be freed while the handler runs.
+ * Use this function to NULL all handler pointers to \a old_region.
+ */
+void WM_event_modal_handler_region_replace(wmWindow *win, const ARegion *old_region, ARegion *new_region)
+{
+       for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
+               if (handler->op_region == old_region) {
+                       handler->op_region = new_region;
+                       handler->op_region_type = new_region ? new_region->regiontype : RGN_TYPE_WINDOW;
+               }
+       }
+}
+
 wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
 {
        wmEventHandler *handler;