Cleanup: split keymap handling into functions
authorCampbell Barton <ideasman42@gmail.com>
Thu, 23 May 2019 04:01:50 +0000 (14:01 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 23 May 2019 04:08:28 +0000 (14:08 +1000)
Move keymap handler logic for keymap and gizmo handlers
into their own functions.

This makes it possible to refactor keymap handling
without large changes or duplicating code.

source/blender/windowmanager/intern/wm_event_system.c

index 6683085..0208ff1 100644 (file)
@@ -2484,15 +2484,134 @@ static int wm_action_not_handled(int action)
   return action == WM_HANDLER_CONTINUE || action == (WM_HANDLER_BREAK | WM_HANDLER_MODAL);
 }
 
+#define PRINT \
+  if (do_debug_handler) \
+  printf
+
+static int wm_handlers_do_keymap_with_keymap_handler(
+    /* From 'wm_handlers_do_intern' */
+    bContext *C,
+    wmEvent *event,
+    ListBase *handlers,
+    wmEventHandler_Keymap *handler,
+    /* Additional. */
+    wmKeyMap *keymap,
+    const bool do_debug_handler)
+{
+  int action = WM_HANDLER_CONTINUE;
+
+  PRINT("%s:   checking '%s' ...", __func__, keymap->idname);
+
+  if (keymap == NULL) {
+    /* Only callback is allowed to have NULL keymaps. */
+    BLI_assert(handler->dynamic.keymap_fn);
+  }
+  else {
+    if (WM_keymap_poll(C, keymap)) {
+
+      PRINT("pass\n");
+
+      for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
+        if (wm_eventmatch(event, kmi)) {
+          struct wmEventHandler_KeymapPost keymap_post = handler->post;
+
+          PRINT("%s:     item matched '%s'\n", __func__, kmi->idname);
+
+          /* weak, but allows interactive callback to not use rawkey */
+          event->keymap_idname = kmi->idname;
+
+          action |= wm_handler_operator_call(C, handlers, &handler->head, event, kmi->ptr);
+
+          if (action & WM_HANDLER_BREAK) {
+            /* not always_pass here, it denotes removed handler_base */
+            CLOG_INFO(WM_LOG_HANDLERS, 2, "handled! '%s'", kmi->idname);
+            if (keymap_post.post_fn != NULL) {
+              keymap_post.post_fn(keymap, kmi, keymap_post.user_data);
+            }
+            break;
+          }
+          else {
+            if (action & WM_HANDLER_HANDLED) {
+              CLOG_INFO(WM_LOG_HANDLERS, 2, "handled - and pass on! '%s'", kmi->idname);
+            }
+            else {
+              CLOG_INFO(WM_LOG_HANDLERS, 2, "un-handled '%s'", kmi->idname);
+            }
+          }
+        }
+      }
+    }
+    else {
+      PRINT("fail\n");
+    }
+  }
+
+  return action;
+}
+
+static bool wm_handlers_do_keymap_with_gizmo_handler(
+    /* From 'wm_handlers_do_intern' */
+    bContext *C,
+    wmEvent *event,
+    ListBase *handlers,
+    wmEventHandler_Gizmo *handler,
+    /* Additional. */
+    wmGizmoGroup *gzgroup,
+    wmKeyMap *keymap,
+    const bool do_debug_handler)
+{
+  int action = WM_HANDLER_CONTINUE;
+  wmKeyMapItem *kmi;
+
+  PRINT("%s:   checking '%s' ...", __func__, keymap->idname);
+
+  if (WM_keymap_poll(C, keymap)) {
+    PRINT("pass\n");
+    for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
+      if (wm_eventmatch(event, kmi)) {
+        PRINT("%s:     item matched '%s'\n", __func__, kmi->idname);
+
+        /* weak, but allows interactive callback to not use rawkey */
+        event->keymap_idname = kmi->idname;
+
+        CTX_wm_gizmo_group_set(C, gzgroup);
+
+        /* handler->op is called later, we want keymap op to be triggered here */
+        action |= wm_handler_operator_call(C, handlers, &handler->head, event, kmi->ptr);
+
+        CTX_wm_gizmo_group_set(C, NULL);
+
+        if (action & WM_HANDLER_BREAK) {
+          if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) {
+            printf("%s:       handled - and pass on! '%s'\n", __func__, kmi->idname);
+          }
+          break;
+        }
+        else {
+          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");
+  }
+  return action;
+}
+
 static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers)
 {
   const bool do_debug_handler =
       (G.debug & G_DEBUG_HANDLERS) &&
       /* comment this out to flood the console! (if you really want to test) */
       !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE);
-#define PRINT \
-  if (do_debug_handler) \
-  printf
 
   wmWindowManager *wm = CTX_wm_manager(C);
   int action = WM_HANDLER_CONTINUE;
@@ -2530,50 +2649,8 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
       if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) {
         wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base;
         wmKeyMap *keymap = WM_event_get_keymap_from_handler(wm, handler);
-
-        PRINT("%s:   checking '%s' ...", __func__, keymap->idname);
-
-        if (keymap == NULL) {
-          /* Only callback is allowed to have NULL keymaps. */
-          BLI_assert(handler->dynamic.keymap_fn);
-        }
-        else if (WM_keymap_poll(C, keymap)) {
-
-          PRINT("pass\n");
-
-          for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
-            if (wm_eventmatch(event, kmi)) {
-              struct wmEventHandler_KeymapPost keymap_post = handler->post;
-
-              PRINT("%s:     item matched '%s'\n", __func__, kmi->idname);
-
-              /* weak, but allows interactive callback to not use rawkey */
-              event->keymap_idname = kmi->idname;
-
-              action |= wm_handler_operator_call(C, handlers, handler_base, event, kmi->ptr);
-
-              if (action & WM_HANDLER_BREAK) {
-                /* not always_pass here, it denotes removed handler_base */
-                CLOG_INFO(WM_LOG_HANDLERS, 2, "handled! '%s'", kmi->idname);
-                if (keymap_post.post_fn != NULL) {
-                  keymap_post.post_fn(keymap, kmi, keymap_post.user_data);
-                }
-                break;
-              }
-              else {
-                if (action & WM_HANDLER_HANDLED) {
-                  CLOG_INFO(WM_LOG_HANDLERS, 2, "handled - and pass on! '%s'", kmi->idname);
-                }
-                else {
-                  CLOG_INFO(WM_LOG_HANDLERS, 2, "un-handled '%s'", kmi->idname);
-                }
-              }
-            }
-          }
-        }
-        else {
-          PRINT("fail\n");
-        }
+        action |= wm_handlers_do_keymap_with_keymap_handler(
+            C, event, handlers, handler, keymap, do_debug_handler);
       }
       else if (handler_base->type == WM_HANDLER_TYPE_UI) {
         wmEventHandler_UI *handler = (wmEventHandler_UI *)handler_base;
@@ -2656,96 +2733,34 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
         }
         else {
           /* Either we operate on a single highlighted item
-           * or groups attached to the selected gizmos.
-           * To simplify things both cases loop over an array of items. */
-          wmGizmoGroup *gzgroup_first;
-          bool is_gzgroup_single;
+           * or groups attached to the selected gizmos. */
+
+          wmGizmoGroup *gzgroup_highlight = gz ? gz->parent_gzgroup : NULL;
+          /* Don't use from now on. */
+          gz = NULL;
 
           if (ISMOUSE(event->type)) {
-            /* Keep gz set as-is, just fake single selection. */
-            if (gz) {
-              gzgroup_first = gz->parent_gzgroup;
-            }
-            else {
-              gzgroup_first = NULL;
+            if (gzgroup_highlight) {
+              wmGizmoGroup *gzgroup = gzgroup_highlight;
+              wmKeyMap *keymap = WM_keymap_active(wm, gzgroup->type->keymap);
+              action |= wm_handlers_do_keymap_with_gizmo_handler(
+                  C, event, handlers, handler, gzgroup, keymap, do_debug_handler);
             }
-            is_gzgroup_single = true;
           }
           else {
             if (WM_gizmomap_is_any_selected(gzmap)) {
               const ListBase *groups = WM_gizmomap_group_list(gzmap);
-              gzgroup_first = groups->first;
-            }
-            else {
-              gzgroup_first = NULL;
-            }
-            is_gzgroup_single = false;
-          }
-
-          /* Don't use from now on. */
-          gz = NULL;
-
-          for (wmGizmoGroup *gzgroup = gzgroup_first; gzgroup; gzgroup = gzgroup->next) {
-            /* get user customized keymap from default one */
-
-            if ((is_gzgroup_single == false) &&
-                /* We might want to change the logic here and use some kind of gizmo edit-mode.
-                 * For now just use keymap when a selection exists. */
-                wm_gizmogroup_is_any_selected(gzgroup) == false) {
-              continue;
-            }
-
-            wmKeyMap *keymap = WM_keymap_active(wm, gzgroup->type->keymap);
-            wmKeyMapItem *kmi;
-
-            PRINT("%s:   checking '%s' ...", __func__, keymap->idname);
-
-            if (WM_keymap_poll(C, keymap)) {
-              PRINT("pass\n");
-              for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
-                if (wm_eventmatch(event, kmi)) {
-                  PRINT("%s:     item matched '%s'\n", __func__, kmi->idname);
-
-                  /* weak, but allows interactive callback to not use rawkey */
-                  event->keymap_idname = kmi->idname;
-
-                  CTX_wm_gizmo_group_set(C, gzgroup);
-
-                  /* handler->op is called later, we want keymap op to be triggered here */
-                  action |= wm_handler_operator_call(C, handlers, handler_base, event, kmi->ptr);
-
-                  CTX_wm_gizmo_group_set(C, NULL);
-
+              for (wmGizmoGroup *gzgroup = groups->first; gzgroup; gzgroup = gzgroup->next) {
+                if (wm_gizmogroup_is_any_selected(gzgroup)) {
+                  wmKeyMap *keymap = WM_keymap_active(wm, gzgroup->type->keymap);
+                  action |= wm_handlers_do_keymap_with_gizmo_handler(
+                      C, event, handlers, handler, gzgroup, keymap, do_debug_handler);
                   if (action & WM_HANDLER_BREAK) {
-                    if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) {
-                      printf("%s:       handled - and pass on! '%s'\n", __func__, kmi->idname);
-                    }
                     break;
                   }
-                  else {
-                    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");
-            }
-
-            if (action & WM_HANDLER_BREAK) {
-              break;
-            }
-
-            if (is_gzgroup_single) {
-              break;
-            }
           }
         }
 
@@ -2802,11 +2817,11 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
     wm_cursor_arrow_move(CTX_wm_window(C), event);
   }
 
-#undef PRINT
-
   return action;
 }
 
+#undef PRINT
+
 /* this calls handlers twice - to solve (double-)click events */
 static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
 {