[Bf-blender-cvs] [b9bb752e0e8] master: UI: search menus from all visible areas when using the edit menu

Campbell Barton noreply at git.blender.org
Wed May 6 14:41:08 CEST 2020


Commit: b9bb752e0e852ddc87e42673caf290283137ec04
Author: Campbell Barton
Date:   Wed May 6 22:32:03 2020 +1000
Branches: master
https://developer.blender.org/rBb9bb752e0e852ddc87e42673caf290283137ec04

UI: search menus from all visible areas when using the edit menu

Without this, only actions in the top-bar were visible
which isn't very useful.

Now menus are extracted from the areas used in the active window,
unless this search is activated by the key shortcut,
in this case the current area is used.

===================================================================

M	source/blender/editors/interface/interface_template_search_menu.c

===================================================================

diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index 3d07da083e8..c256923e7fd 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -64,6 +64,12 @@
 /* Unicode arrow. */
 #define MENU_SEP "\xe2\x96\xb6"
 
+struct MenuSearch_Context {
+  int space_type_ui_index;
+  ScrArea *area;
+  ARegion *region;
+};
+
 struct MenuSearch_Parent {
   struct MenuSearch_Parent *parent;
   MenuType *parent_mt;
@@ -107,6 +113,12 @@ struct MenuSearch_Item {
       int enum_value;
     } rna;
   };
+
+  /**
+   * Set when we need each menu item to be able to set it's own context.
+   * may be NULL.
+   */
+  struct MenuSearch_Context *wm_context;
 };
 
 struct MenuSearch_Data {
@@ -143,7 +155,8 @@ static bool menu_items_from_ui_create_item_from_button(struct MenuSearch_Data *d
                                                        MemArena *memarena,
                                                        struct MenuType *mt,
                                                        const char *drawstr_submenu,
-                                                       uiBut *but)
+                                                       uiBut *but,
+                                                       struct MenuSearch_Context *wm_context)
 {
   struct MenuSearch_Item *item = NULL;
   if (but->optype != NULL) {
@@ -187,6 +200,9 @@ static bool menu_items_from_ui_create_item_from_button(struct MenuSearch_Data *d
     item->state = (but->flag & (UI_BUT_DISABLED | UI_BUT_INACTIVE | UI_BUT_REDALERT));
     item->mt = mt;
     item->drawstr_submenu = drawstr_submenu ? strdup_memarena(memarena, drawstr_submenu) : NULL;
+
+    item->wm_context = wm_context;
+
     BLI_addtail(&data->items, item);
     return true;
   }
@@ -289,6 +305,8 @@ static void menu_items_from_all_operators(bContext *C, struct MenuSearch_Data *d
 
       item->drawwstr_full = strdup_memarena(memarena, uiname);
 
+      item->wm_context = NULL;
+
       BLI_addtail(&operator_items, item);
     }
   }
@@ -304,10 +322,8 @@ static void menu_items_from_all_operators(bContext *C, struct MenuSearch_Data *d
  * - Look-up pre-defined editor-menus.
  * - Look-up key-map items which call menus.
  */
-static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C,
-                                                         wmWindow *win,
-                                                         ScrArea *area,
-                                                         ARegion *region)
+static struct MenuSearch_Data *menu_items_from_ui_create(
+    bContext *C, wmWindow *win, ScrArea *area_init, ARegion *region_init, bool include_all_areas)
 {
   MemArena *memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
   /** Map (#MenuType to #MenuSearch_Parent) */
@@ -344,17 +360,113 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C,
     }
   }
 
-  /* Populate menus from the editors,
-   * note that we could create a fake header, draw the header and extract the menus
-   * from the buttons, however this is quite involved and can be avoided as by convention
-   * each space-type has a single root-menu that headers use. */
-  {
-    const char *idname_array[] = {
-        "TOPBAR_MT_editor_menus",
-        /* Optional second menu for the space-type. */
-        NULL,
-    };
-    int idname_array_len = 1;
+  /* Collect contexts, one for each 'ui_type'. */
+  struct MenuSearch_Context *wm_contexts = NULL;
+
+  const EnumPropertyItem *space_type_ui_items = NULL;
+  int space_type_ui_items_len;
+  bool space_type_ui_items_free = false;
+
+  /* Types match, cycle the subtype. */
+
+  if (include_all_areas) {
+    /* First create arrays for ui_type. */
+    PropertyRNA *prop_ui_type;
+    {
+      PointerRNA ptr;
+      RNA_pointer_create(NULL, &RNA_Area, NULL, &ptr);
+      prop_ui_type = RNA_struct_find_property(&ptr, "ui_type");
+      RNA_property_enum_items(C,
+                              &ptr,
+                              prop_ui_type,
+                              &space_type_ui_items,
+                              &space_type_ui_items_len,
+                              &space_type_ui_items_free);
+
+      wm_contexts = BLI_memarena_alloc(memarena, sizeof(*wm_contexts) * space_type_ui_items_len);
+
+      for (int i = 0; i < space_type_ui_items_len; i++) {
+        wm_contexts[i].space_type_ui_index = -1;
+        wm_contexts[i].area = NULL;
+        wm_contexts[i].region = NULL;
+      }
+    }
+
+    bScreen *screen = WM_window_get_active_screen(win);
+    LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+      ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
+      if (region != NULL) {
+        PointerRNA ptr;
+        RNA_pointer_create(&screen->id, &RNA_Area, area, &ptr);
+        const int space_type_ui = RNA_property_enum_get(&ptr, prop_ui_type);
+
+        int space_type_ui_index = RNA_enum_from_value(space_type_ui_items, space_type_ui);
+        if (space_type_ui_index == -1) {
+          continue;
+        }
+
+        if (wm_contexts[space_type_ui_index].space_type_ui_index != -1) {
+          ScrArea *area_best = wm_contexts[area->spacetype].area;
+          const uint value_best = (uint)area_best->winx * (uint)area_best->winy;
+          const uint value_test = (uint)area->winx * (uint)area->winy;
+          if (value_best > value_test) {
+            continue;
+          }
+        }
+
+        wm_contexts[space_type_ui_index].space_type_ui_index = space_type_ui_index;
+        wm_contexts[space_type_ui_index].area = area;
+        wm_contexts[space_type_ui_index].region = region;
+      }
+    }
+  }
+
+  GHashIterator iter;
+
+  for (int space_type_ui_index = -1; space_type_ui_index < space_type_ui_items_len;
+       space_type_ui_index += 1) {
+
+    ScrArea *area = NULL;
+    ARegion *region = NULL;
+    struct MenuSearch_Context *wm_context = NULL;
+
+    if (include_all_areas) {
+      if (space_type_ui_index == -1) {
+        /* First run without any context, to populate the top-bar without. */
+        wm_context = NULL;
+        area = NULL;
+        region = NULL;
+      }
+      else {
+        wm_context = &wm_contexts[space_type_ui_index];
+        if (wm_context->space_type_ui_index == -1) {
+          continue;
+        }
+
+        area = wm_context->area;
+        region = wm_context->region;
+
+        CTX_wm_area_set(C, area);
+        CTX_wm_region_set(C, region);
+      }
+    }
+    else {
+      area = area_init;
+      region = region_init;
+    }
+
+    /* Populate menus from the editors,
+     * note that we could create a fake header, draw the header and extract the menus
+     * from the buttons, however this is quite involved and can be avoided as by convention
+     * each space-type has a single root-menu that headers use. */
+    {
+      const char *idname_array[2] = {NULL};
+      int idname_array_len = 0;
+
+      /* Use negative for global (no area) context, populate the top-bar. */
+      if (space_type_ui_index == -1) {
+        idname_array[idname_array_len++] = "TOPBAR_MT_editor_menus";
+      }
 
 #define SPACE_MENU_MAP(space_type, menu_id) \
   case space_type: \
@@ -364,177 +476,180 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C,
   case space_type: \
     break
 
-    if (area != NULL) {
-      switch (area->spacetype) {
-        SPACE_MENU_MAP(SPACE_VIEW3D, "VIEW3D_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_GRAPH, "GRAPH_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_OUTLINER, "OUTLINER_MT_editor_menus");
-        SPACE_MENU_NOP(SPACE_PROPERTIES);
-        SPACE_MENU_MAP(SPACE_FILE, "FILE_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_IMAGE, "IMAGE_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_INFO, "INFO_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_SEQ, "SEQUENCER_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_TEXT, "TEXT_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_ACTION, "DOPESHEET_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_NLA, "NLA_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_NODE, "NODE_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_CONSOLE, "CONSOLE_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_USERPREF, "USERPREF_MT_editor_menus");
-        SPACE_MENU_MAP(SPACE_CLIP,
-                       (((const SpaceClip *)area->spacedata.first)->mode == SC_MODE_TRACKING) ?
-                           "CLIP_MT_tracking_editor_menus" :
-                           "CLIP_MT_masking_editor_menus");
-        SPACE_MENU_NOP(SPACE_TOPBAR);
-        SPACE_MENU_NOP(SPACE_STATUSBAR);
-        default:
-          printf("Unknown space type '%d'\n", area->spacetype);
+      if (area != NULL) {
+        switch (area->spacetype) {
+          SPACE_MENU_MAP(SPACE_VIEW3D, "VIEW3D_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_GRAPH, "GRAPH_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_OUTLINER, "OUTLINER_MT_editor_menus");
+          SPACE_MENU_NOP(SPACE_PROPERTIES);
+          SPACE_MENU_MAP(SPACE_FILE, "FILE_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_IMAGE, "IMAGE_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_INFO, "INFO_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_SEQ, "SEQUENCER_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_TEXT, "TEXT_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_ACTION, "DOPESHEET_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_NLA, "NLA_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_NODE, "NODE_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_CONSOLE, "CONSOLE_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_USERPREF, "USERPREF_MT_editor_menus");
+          SPACE_MENU_MAP(SPACE_CLIP,
+                         (((const SpaceClip *)area->spacedata.first)->mode == SC_MODE_TRACKING) ?
+                             "CLIP_MT_tracking_editor_menus" :
+                             "CLIP_MT_masking_editor_menus");
+          SPACE_MENU_NOP(SPACE_TOPBAR);
+          SPACE_MENU_NOP(SPACE_STATUSBAR);
+          default:
+            printf("Unknown space type '%d'\n", area->spacetype);
+        }
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list