Python: add a utility function for creating custom properties.
authorAlexander Gavrilov <angavrilov@gmail.com>
Sat, 30 Mar 2019 09:53:39 +0000 (12:53 +0300)
committerAlexander Gavrilov <angavrilov@gmail.com>
Tue, 16 Apr 2019 13:49:00 +0000 (16:49 +0300)
Creating a fully functional custom property requires also setting up
its limits, description, default value and static override status.
It is complex enough to warrant providing an official utility.

Currently boolean properties are technically int, but the utility
pretends they are separate in case that eventually they are.

Reviewers: campbellbarton

Differential Revision: https://developer.blender.org/D4620

release/scripts/modules/rna_prop_ui.py
release/scripts/startup/bl_operators/wm.py

index 88c3f37..7fcb5e8 100644 (file)
@@ -39,8 +39,13 @@ def rna_idprop_ui_del(item):
         pass
 
 
+def rna_idprop_quote_path(prop):
+    return "[\"%s\"]" % prop.replace("\"", "\\\"")
+
+
 def rna_idprop_ui_prop_update(item, prop):
-    prop_rna = item.path_resolve("[\"%s\"]" % prop.replace("\"", "\\\""), False)
+    prop_path = rna_idprop_quote_path(prop)
+    prop_rna = item.path_resolve(prop_path, False)
     if isinstance(prop_rna, bpy.types.bpy_prop):
         prop_rna.update()
 
@@ -115,6 +120,53 @@ def rna_idprop_ui_prop_default_set(item, prop, value):
             del rna_ui["default"]
 
 
+def rna_idprop_ui_create(item, prop, default, min=0.0, max=1.0, soft_min=None, soft_max=None, description=None, overridable=False):
+    """Create and initialize a custom property with limits, defaults and other settings."""
+
+    proptype = type(default)
+
+    # Sanitize limits
+    if proptype is bool:
+        min = soft_min = False
+        max = soft_max = True
+
+    if soft_min is None:
+        soft_min = min
+    if soft_max is None:
+        soft_max = max
+
+    # Assign the value
+    item[prop] = default
+
+    rna_idprop_ui_prop_update(item, prop)
+
+    # Clear the UI settings
+    rna_ui_group = rna_idprop_ui_get(item, True)
+    rna_ui_group[prop] = {}
+    rna_ui = rna_ui_group[prop]
+
+    # Assign limits and default
+    if proptype in {int, float, bool}:
+        # The type must be exactly the same
+        rna_ui["min"] = proptype(min)
+        rna_ui["soft_min"] = proptype(soft_min)
+        rna_ui["max"] = proptype(max)
+        rna_ui["soft_max"] = proptype(soft_max)
+
+        if default:
+            rna_ui["default"] = default
+
+    # Assign other settings
+    if description is not None:
+        rna_ui["description"] = description
+
+    prop_path = rna_idprop_quote_path(prop)
+
+    item.property_overridable_static_set(prop_path, overridable)
+
+    return rna_ui
+
+
 def draw(layout, context, context_member, property_type, use_edit=True):
 
     def assign_props(prop, val, key):
index de811d4..e22f50d 100644 (file)
@@ -1322,8 +1322,7 @@ class WM_OT_properties_add(Operator):
 
     def execute(self, context):
         from rna_prop_ui import (
-            rna_idprop_ui_prop_get,
-            rna_idprop_ui_prop_update,
+            rna_idprop_ui_create,
         )
 
         data_path = self.data_path
@@ -1344,13 +1343,7 @@ class WM_OT_properties_add(Operator):
             *type(item).bl_rna.properties.keys(),
         })
 
-        item[prop] = 1.0
-        rna_idprop_ui_prop_update(item, prop)
-
-        # not essential, but without this we get [#31661]
-        prop_ui = rna_idprop_ui_prop_get(item, prop)
-        prop_ui["soft_min"] = prop_ui["min"] = 0.0
-        prop_ui["soft_max"] = prop_ui["max"] = 1.0
+        rna_idprop_ui_create(item, prop, 1.0)
 
         return {'FINISHED'}