diff options
Diffstat (limited to 'release/scripts/startup/bl_operators/wm.py')
-rw-r--r-- | release/scripts/startup/bl_operators/wm.py | 85 |
1 files changed, 75 insertions, 10 deletions
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 170b9f3ae44..28bb0a58c02 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1298,6 +1298,13 @@ rna_vector_subtype_items = ( ('QUATERNION', "Quaternion Rotation", "Quaternion rotation (affects NLA blending)"), ) + +# NOTE: needed for Python 3.10 since there are name-space issues with annotations. +# This can be moved into the class as a static-method once Python 3.9x is dropped. +def _wm_properties_edit_subtype_items(_self, _context): + return WM_OT_properties_edit.subtype_items + + class WM_OT_properties_edit(Operator): """Change a custom property's type, or adjust how it is displayed in the interface""" bl_idname = "wm.properties_edit" @@ -1312,7 +1319,7 @@ class WM_OT_properties_edit(Operator): property_name: rna_custom_property_name property_type: EnumProperty( name="Type", - items=lambda self, _context: WM_OT_properties_edit.type_items, + items=rna_custom_property_type_items, ) is_overridable_library: BoolProperty( name="Is Library Overridable", @@ -1404,7 +1411,7 @@ class WM_OT_properties_edit(Operator): ) subtype: EnumProperty( name="Subtype", - items=lambda self, _context: WM_OT_properties_edit.subtype_items, + items=_wm_properties_edit_subtype_items, ) # String properties. @@ -1442,7 +1449,7 @@ class WM_OT_properties_edit(Operator): # Convert an old property for a string, avoiding unhelpful string representations for custom list types. @staticmethod - def _convert_old_property_to_string(item, name): + def convert_custom_property_to_string(item, name): # The IDProperty group view API currently doesn't have a "lookup" method. for key, value in item.items(): if key == name: @@ -1461,7 +1468,8 @@ class WM_OT_properties_edit(Operator): # Retrieve the current type of the custom property on the RNA struct. Some properties like group properties # can be created in the UI, but editing their meta-data isn't supported. In that case, return 'PYTHON'. - def _get_property_type(self, item, property_name): + @staticmethod + def get_property_type(item, property_name): from rna_prop_ui import ( rna_idprop_value_item_type, ) @@ -1549,17 +1557,17 @@ class WM_OT_properties_edit(Operator): return self._convert_new_value_single(item[name_old], float) if prop_type_new == 'INT_ARRAY': - prop_type_old = self._get_property_type(item, name_old) + prop_type_old = self.get_property_type(item, name_old) if prop_type_old in {'INT', 'FLOAT', 'INT_ARRAY', 'FLOAT_ARRAY'}: return self._convert_new_value_array(item[name_old], int, self.array_length) if prop_type_new == 'FLOAT_ARRAY': - prop_type_old = self._get_property_type(item, name_old) + prop_type_old = self.get_property_type(item, name_old) if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY'}: return self._convert_new_value_array(item[name_old], float, self.array_length) if prop_type_new == 'STRING': - return self._convert_old_property_to_string(item, name_old) + return self.convert_custom_property_to_string(item, name_old) # If all else fails, create an empty string property. That should avoid errors later on anyway. return "" @@ -1672,7 +1680,7 @@ class WM_OT_properties_edit(Operator): self.report({'ERROR'}, "Cannot edit properties from override data") return {'CANCELLED'} - prop_type_old = self._get_property_type(item, name_old) + prop_type_old = self.get_property_type(item, name_old) prop_type_new = self.property_type self._old_prop_name[:] = [name] @@ -1716,14 +1724,14 @@ class WM_OT_properties_edit(Operator): return {'CANCELLED'} # Set operator's property type with the type of the existing property, to display the right settings. - old_type = self._get_property_type(item, name) + old_type = self.get_property_type(item, name) self.property_type = old_type self.last_property_type = old_type # So that the operator can do something for unsupported properties, change the property into # a string, just for editing in the dialog. When the operator executes, it will be converted back # into a python value. Always do this conversion, in case the Python property edit type is selected. - self.eval_string = self._convert_old_property_to_string(item, name) + self.eval_string = self.convert_custom_property_to_string(item, name) if old_type != 'PYTHON': self._fill_old_ui_data(item, name) @@ -1845,6 +1853,62 @@ class WM_OT_properties_edit(Operator): layout.prop(self, "description") +# Edit the value of a custom property with the given name on the RNA struct at the given data path. +# For supported types, this simply acts as a convenient way to create a popup for a specific property +# and draws the custom property value directly in the popup. For types like groups which can't be edited +# directly with buttons, instead convert the value to a string, evaluate the changed string when executing. +class WM_OT_properties_edit_value(Operator): + """Edit the value of a custom property""" + bl_idname = "wm.properties_edit_value" + bl_label = "Edit Property Value" + # register only because invoke_props_popup requires. + bl_options = {'REGISTER', 'INTERNAL'} + + data_path: rna_path + property_name: rna_custom_property_name + + # Store the value converted to a string as a fallback for otherwise unsupported types. + eval_string: StringProperty( + name="Value", + description="Value for custom property types that can only be edited as a Python expression" + ) + + def execute(self, context): + if self.eval_string: + rna_item = eval("context.%s" % self.data_path) + try: + new_value = eval(self.eval_string) + except Exception as ex: + self.report({'WARNING'}, "Python evaluation failed: " + str(ex)) + return {'CANCELLED'} + rna_item[self.property_name] = new_value + return {'FINISHED'} + + def invoke(self, context, _event): + rna_item = eval("context.%s" % self.data_path) + + if WM_OT_properties_edit.get_property_type(rna_item, self.property_name) == 'PYTHON': + self.eval_string = WM_OT_properties_edit.convert_custom_property_to_string(rna_item, + self.property_name) + else: + self.eval_string = "" + + wm = context.window_manager + return wm.invoke_props_dialog(self) + + def draw(self, context): + from bpy.utils import escape_identifier + + rna_item = eval("context.%s" % self.data_path) + + layout = self.layout + if WM_OT_properties_edit.get_property_type(rna_item, self.property_name) == 'PYTHON': + layout.prop(self, "eval_string") + else: + col = layout.column(align=True) + col.prop(rna_item, '["%s"]' % escape_identifier(self.property_name), text="") + + class WM_OT_properties_add(Operator): """Add your own property to the data-block""" bl_idname = "wm.properties_add" @@ -3056,6 +3120,7 @@ classes = ( WM_OT_properties_add, WM_OT_properties_context_change, WM_OT_properties_edit, + WM_OT_properties_edit_value, WM_OT_properties_remove, WM_OT_sysinfo, WM_OT_owner_disable, |