inspector_plugins.rst 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. .. _doc_inspector_plugins:
  2. Inspector plugins
  3. =================
  4. The inspector dock supports custom plugins to create your own widgets for
  5. editing properties. This tutorial explains how to use the
  6. :ref:`class_EditorInspectorPlugin` and :ref:`class_EditorProperty` classes to
  7. write such plugins with the example of creating a custom value editor.
  8. Setup
  9. -----
  10. Just like :ref:`doc_making_plugins`, we start out by making a new plugin,
  11. getting a ``plugin.cfg`` file created, and start with our
  12. :ref:`class_EditorPlugin`. However, instead of using
  13. ``add_custom_node`` or ``add_control_to_dock`` we'll use
  14. ``add_inspector_plugin``.
  15. .. tabs::
  16. .. code-tab:: gdscript GDScript
  17. # MyEditorPlugin.gd
  18. tool
  19. extends EditorPlugin
  20. var plugin
  21. func _enter_tree():
  22. # EditorInspectorPlugin is a resource, so we use `new()` instead of `instance()`.
  23. plugin = preload("res://addons/MyPlugin/MyInspectorPlugin.gd").new()
  24. add_inspector_plugin(plugin)
  25. func _exit_tree():
  26. remove_inspector_plugin(plugin)
  27. EditorInspectorPlugin
  28. ---------------------
  29. To actually connect into the Inspector, we create a
  30. :ref:`class_EditorInspectorPlugin` class. This script provides the "hooks" to
  31. the inspector. Thanks to this class, the editor will call the functions within
  32. the EditorInspectorPlugin while it goes through the process of building the UI
  33. for the inspector. The script is used to check if we should enable ourselves for
  34. any :ref:`class_Object` that is currently in the inspector (including any
  35. :ref:`class_Resource` that is embedded!).
  36. Once enabled, EditorInspectorPlugin has methods that allow for adding
  37. :ref:`class_EditorProperty` nodes or just custom :ref:`class_Control` nodes to
  38. the beginning and end of the inspector for that :ref:`class_Object`, or for
  39. overriding or changing existing property editors.
  40. .. tabs::
  41. .. code-tab:: gdscript GDScript
  42. # MyInspectorPlugin.gd
  43. extends EditorInspectorPlugin
  44. func can_handle(object):
  45. # Here you can specify which object types (classes) should be handled by
  46. # this plugin. For example if the plugin is specific to your player
  47. # class defined with `class_name MyPlayer`, you can do:
  48. # `return object is MyPlayer`
  49. # In this example we'll support all objects, so:
  50. return true
  51. func parse_property(object, type, path, hint, hint_text, usage):
  52. # We will handle properties of type integer.
  53. if type == TYPE_INT:
  54. # Register *an instance* of the custom property editor that we'll define next.
  55. add_property_editor(path, MyIntEditor.new())
  56. # We return `true` to notify the inspector that we'll be handling
  57. # this integer property, so it doesn't need to parse other plugins
  58. # (including built-in ones) for an appropriate editor.
  59. return true
  60. else:
  61. return false
  62. EditorProperty
  63. --------------
  64. Next, we define the actual :ref:`class_EditorProperty` custom value editor that
  65. we want instantiated to edit integers. This is a custom :ref:`class_Control` and
  66. we can add any kinds of additional nodes to make advanced widgets to embed in
  67. the inspector.
  68. .. tabs::
  69. .. code-tab:: gdscript GDScript
  70. # MyIntEditor.gd
  71. extends EditorProperty
  72. class_name MyIntEditor
  73. var updating = false
  74. var spin = EditorSpinSlider.new()
  75. func _init():
  76. # We'll add an EditorSpinSlider control, which is the same that the
  77. # inspector already uses for integer and float edition.
  78. # If you want to put the editor below the property name, use:
  79. # `set_bottom_editor(spin)`
  80. # Otherwise to put it inline with the property name use:
  81. add_child(spin)
  82. # To remember focus when selected back:
  83. add_focusable(spin)
  84. # Setup the EditorSpinSlider
  85. spin.set_min(0)
  86. spin.set_max(1000)
  87. spin.connect("value_changed", self, "_spin_changed")
  88. func _spin_changed(value):
  89. if (updating):
  90. return
  91. emit_changed(get_edited_property(), value)
  92. func update_property():
  93. var new_value = get_edited_object()[get_edited_property()]
  94. updating = true
  95. spin.set_value(new_value)
  96. updating = false