[Bf-blender-cvs] [3f3d82cfe9c] master: UI support for showing candidates for string properties

Campbell Barton noreply at git.blender.org
Thu May 26 04:17:19 CEST 2022


Commit: 3f3d82cfe9cefe4bfd9da3d283dec4a1923ec22d
Author: Campbell Barton
Date:   Fri May 20 14:30:17 2022 +1000
Branches: master
https://developer.blender.org/rB3f3d82cfe9cefe4bfd9da3d283dec4a1923ec22d

UI support for showing candidates for string properties

Currently strings are used for cases where a list of identifiers would
be useful to show.

Add support for string properties to reference a callback to populate
candidates to show when editing a string. The user isn't prevented from
typing in text not found in this list, it's just useful as a reference.

Support for expanding the following strings has been added:

- Operator, menu & panel identifiers in the keymap editor.
- WM operators that reference data-paths expand using the
  Python-consoles auto-complete functionality.
- Names of keying sets for insert/delete keyframe operators.

Details:

- `bpy.props.StringProperty` takes an option `search` callback.

- A new string callback has been added, set via
  `RNA_def_property_string_search_func` or
  `RNA_def_property_string_search_func_runtime`.

- Addresses usability issue highlighted by T89560,
  where setting keying set identifiers as strings isn't practical.

- Showing additional right-aligned text in the search results is
  supported but disabled by default as the text is too cramped in most
  string search popups where the feature would make sense. It could be
  enabled as part of other layout tweaks.

Reviewed By: brecht

Ref D14986

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

M	release/scripts/startup/bl_operators/wm.py
M	source/blender/blenkernel/BKE_global.h
M	source/blender/editors/animation/keyframing.c
M	source/blender/editors/animation/keyingsets.c
M	source/blender/editors/include/ED_keyframing.h
M	source/blender/editors/interface/interface_layout.c
M	source/blender/editors/interface/interface_utils.cc
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/RNA_define.h
M	source/blender/makesrna/RNA_types.h
M	source/blender/makesrna/intern/makesrna.c
M	source/blender/makesrna/intern/rna_access.c
M	source/blender/makesrna/intern/rna_define.c
M	source/blender/makesrna/intern/rna_internal_types.h
M	source/blender/makesrna/intern/rna_wm.c
M	source/blender/python/intern/bpy_props.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_menu_type.c
M	source/blender/windowmanager/intern/wm_operator_type.c
M	source/blender/windowmanager/intern/wm_operators.c
M	source/blender/windowmanager/intern/wm_panel_type.c

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

diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 0f063da40fb..09dbd2e5334 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -21,10 +21,28 @@ from bpy.props import (
 )
 from bpy.app.translations import pgettext_iface as iface_
 
+
+def rna_path_prop_search_for_context(self, context, edit_text):
+    # Use the same logic as auto-completing in the Python console to expand the data-path.
+    from bl_console_utils.autocomplete import intellisense
+    context_prefix = "context."
+    line = context_prefix + edit_text
+    cursor = len(line)
+    namespace = {"context": context}
+    comp_prefix, _, comp_options = intellisense.expand(line=line, cursor=len(line), namespace=namespace, private=False)
+    prefix = comp_prefix[len(context_prefix):]  # Strip "context."
+    for attr in comp_options.split("\n"):
+        # Exclude function calls because they are generally not part of data-paths.
+        if attr.endswith(("(", ")")):
+            continue
+        yield prefix + attr.lstrip()
+
+
 rna_path_prop = StringProperty(
     name="Context Attributes",
     description="RNA context string",
     maxlen=1024,
+    search=rna_path_prop_search_for_context,
 )
 
 rna_reverse_prop = BoolProperty(
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 06feb07aef2..96b6f7a53b0 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -81,6 +81,7 @@ typedef struct Global {
    *   * 1 - 30: EEVEE debug/stats values (01/2018).
    *   *     31: Enable the Select Debug Engine. Only available with #WITH_DRAW_DEBUG (08/2021).
    *   *    101: Enable UI debug drawing of fullscreen area's corner widget (10/2014).
+   *   *    102: Enable extra items in string search UI (05/2022).
    *   *    666: Use quicker batch delete for outliners' delete hierarchy (01/2019).
    *   *    777: Enable UI node panel's sockets polling (11/2011).
    *   *    799: Enable some mysterious new depsgraph behavior (05/2015).
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 14a3b958ea6..941125b9ad5 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -2051,6 +2051,8 @@ void ANIM_OT_keyframe_insert_by_name(wmOperatorType *ot)
   /* keyingset to use (idname) */
   prop = RNA_def_string(
       ot->srna, "type", NULL, MAX_ID_NAME - 2, "Keying Set", "The Keying Set to use");
+  RNA_def_property_string_search_func_runtime(
+      prop, ANIM_keyingset_visit_for_search_no_poll, PROP_STRING_SEARCH_SUGGESTION);
   RNA_def_property_flag(prop, PROP_HIDDEN);
   ot->prop = prop;
 }
@@ -2246,6 +2248,8 @@ void ANIM_OT_keyframe_delete_by_name(wmOperatorType *ot)
   /* keyingset to use (idname) */
   prop = RNA_def_string(
       ot->srna, "type", NULL, MAX_ID_NAME - 2, "Keying Set", "The Keying Set to use");
+  RNA_def_property_string_search_func_runtime(
+      prop, ANIM_keyingset_visit_for_search_no_poll, PROP_STRING_SEARCH_SUGGESTION);
   RNA_def_property_flag(prop, PROP_HIDDEN);
   ot->prop = prop;
 }
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 6fcdd21bad8..97b81277008 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -708,6 +708,72 @@ KeyingSet *ANIM_get_keyingset_for_autokeying(const Scene *scene, const char *tra
   return ANIM_builtin_keyingset_get_named(NULL, transformKSName);
 }
 
+static void anim_keyingset_visit_for_search_impl(const bContext *C,
+                                                 StringPropertySearchVisitFunc visit_fn,
+                                                 void *visit_user_data,
+                                                 const bool use_poll)
+{
+  /* Poll requires context.  */
+  if (use_poll && (C == NULL)) {
+    return;
+  }
+
+  Scene *scene = C ? CTX_data_scene(C) : NULL;
+  KeyingSet *ks;
+
+  /* Active Keying Set. */
+  if (!use_poll || (scene && scene->active_keyingset)) {
+    StringPropertySearchVisitParams visit_params = {NULL};
+    visit_params.text = "__ACTIVE__";
+    visit_params.info = "Active Keying Set";
+    visit_fn(visit_user_data, &visit_params);
+  }
+
+  /* User-defined Keying Sets. */
+  if (scene && scene->keyingsets.first) {
+    for (ks = scene->keyingsets.first; ks; ks = ks->next) {
+      if (use_poll && !ANIM_keyingset_context_ok_poll((bContext *)C, ks)) {
+        continue;
+      }
+      StringPropertySearchVisitParams visit_params = {NULL};
+      visit_params.text = ks->idname;
+      visit_params.info = ks->name;
+      visit_fn(visit_user_data, &visit_params);
+    }
+  }
+
+  /* Builtin Keying Sets. */
+  for (ks = builtin_keyingsets.first; ks; ks = ks->next) {
+    if (use_poll && !ANIM_keyingset_context_ok_poll((bContext *)C, ks)) {
+      continue;
+    }
+    StringPropertySearchVisitParams visit_params = {NULL};
+    visit_params.text = ks->idname;
+    visit_params.info = ks->name;
+    visit_fn(visit_user_data, &visit_params);
+  }
+}
+
+void ANIM_keyingset_visit_for_search(const bContext *C,
+                                     PointerRNA *UNUSED(ptr),
+                                     PropertyRNA *UNUSED(prop),
+                                     const char *UNUSED(edit_text),
+                                     StringPropertySearchVisitFunc visit_fn,
+                                     void *visit_user_data)
+{
+  anim_keyingset_visit_for_search_impl(C, visit_fn, visit_user_data, false);
+}
+
+void ANIM_keyingset_visit_for_search_no_poll(const bContext *C,
+                                             PointerRNA *UNUSED(ptr),
+                                             PropertyRNA *UNUSED(prop),
+                                             const char *UNUSED(edit_text),
+                                             StringPropertySearchVisitFunc visit_fn,
+                                             void *visit_user_data)
+{
+  anim_keyingset_visit_for_search_impl(C, visit_fn, visit_user_data, true);
+}
+
 /* Menu of All Keying Sets ----------------------------- */
 
 const EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C,
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 6a730225da9..8c0147612fb 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -351,6 +351,19 @@ int ANIM_scene_get_keyingset_index(struct Scene *scene, struct KeyingSet *ks);
 struct KeyingSet *ANIM_get_keyingset_for_autokeying(const struct Scene *scene,
                                                     const char *transformKSName);
 
+void ANIM_keyingset_visit_for_search(const struct bContext *C,
+                                     struct PointerRNA *ptr,
+                                     struct PropertyRNA *prop,
+                                     const char *edit_text,
+                                     StringPropertySearchVisitFunc visit_fn,
+                                     void *visit_user_data);
+
+void ANIM_keyingset_visit_for_search_no_poll(const struct bContext *C,
+                                             struct PointerRNA *ptr,
+                                             struct PropertyRNA *prop,
+                                             const char *edit_text,
+                                             StringPropertySearchVisitFunc visit_fn,
+                                             void *visit_user_data);
 /**
  * Dynamically populate an enum of Keying Sets.
  */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 933d7efb4d6..3465373c85d 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -2338,7 +2338,14 @@ void uiItemFullR(uiLayout *layout,
   /* property with separate label */
   else if (ELEM(type, PROP_ENUM, PROP_STRING, PROP_POINTER)) {
     but = ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, flag);
-    but = ui_but_add_search(but, ptr, prop, NULL, NULL, false);
+    bool results_are_suggestions = false;
+    if (type == PROP_STRING) {
+      const eStringPropertySearchFlag search_flag = RNA_property_string_search_flag(prop);
+      if (search_flag & PROP_STRING_SEARCH_SUGGESTION) {
+        results_are_suggestions = true;
+      }
+    }
+    but = ui_but_add_search(but, ptr, prop, NULL, NULL, results_are_suggestions);
 
     if (layout->redalert) {
       UI_but_flag_enable(but, UI_BUT_REDALERT);
@@ -2711,11 +2718,16 @@ uiBut *ui_but_add_search(uiBut *but,
                          PropertyRNA *prop,
                          PointerRNA *searchptr,
                          PropertyRNA *searchprop,
-                         bool results_are_suggestions)
+                         const bool results_are_suggestions)
 {
   /* for ID's we do automatic lookup */
+  bool has_search_fn = false;
+
   PointerRNA sptr;
   if (!searchprop) {
+    if (RNA_property_type(prop) == PROP_STRING) {
+      has_search_fn = (RNA_property_string_search_flag(prop) != 0);
+    }
     if (RNA_property_type(prop) == PROP_POINTER) {
       StructRNA *ptype = RNA_property_pointer_type(ptr, prop);
       search_id_collection(ptype, &sptr, &searchprop);
@@ -2724,14 +2736,18 @@ uiBut *ui_but_add_search(uiBut *but,
   }
 
   /* turn button into search button */
-  if (searchprop) {
+  if (has_search_fn || searchprop) {
     uiRNACollectionSearch *coll_search = MEM_mallocN(sizeof(*coll_search), __func__);
     uiButSearch *search_but;
 
     but = ui_but_change_type(but, UI_BTYPE_SEARCH_MENU);
     search_but = (uiButSearch *)but;
-    search_but->rnasearchpoin = *searchptr;
-    search_but->rnasearchprop = searchprop;
+
+    if (searchptr) {
+      search_but->rnasearchpoin = *searchptr;
+      search_but->rnasearchprop = searchprop;
+    }
+
     but->hardmax = MAX2(but->hardmax, 256.0f);
     but->drawflag |= UI_BUT_ICON_LEFT | UI_B

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list