Basic Requirements of a Drawer
When creating your own drawer for use in Power Inspector, your class needs to fulfill the following requirements:
- The class should be decorated with an attribute that derives from DrawerForBase attribute. This lets Power Inspector know what elements inside the inspector should be handled by the drawer.
- The class should implement one of the interfaces that derives from IDrawer that corresponds with the used attribute.
List of DrawerFor* Attributes
Here are all the available attributes, and the IDrawer-derived interfaces that can be chosen by the classes that have them:
-
- DrawerForField attribute
- IFieldDrawer – Implemented by drawers that represent a value-backed class member such as a field or a property.
- ITextFieldDrawer – An extension of IFieldDrawer for drawers that include a text field.
- DrawerForComponent attribute
- DrawerForAsset attribute
- DrawerByExtension attribute
- DrawerForPropertyDrawer
- IPropertyDrawerDrawer – Implemented by drawers of PropertyDrawers.
- DrawerForDecoratorDrawer
- IDecoratorDrawerDrawer – Implemented by drawers of DecoratorDrawers.
- DrawerForField attribute
Manually Instantiated Drawers
If you don’t need Power Inspector to automatically use your drawers inside the inspector, but instead plan to manually create instances of your drawers (this can happen for example when drawers are only used as members of another drawer), then you don’t need to decorate your drawer with any attributes. The only minimum requirement then is that the class implements IDrawer or an interface that derives from it.
However, drawers in Power Inspector can make use of object pooling to reduce garbage generation. In order to make use of this feature, you’ll need to create a method that can be used to get an instance of your drawer, which handles retrieving existing instances from the drawer pool when they exist and calling the Setup and LateSetup methods on the existing instance. Here is an example of such an implementation for a simple field drawer:
/// <summary> Creates a new instance of the drawer or returns a reusable instance from the pool. </summary> /// <param name="value"> The starting cached value of the drawer. </param> /// <param name="memberInfo"> LinkedMemberInfo for the field, property or parameter that the drawer represents. Can be null. </param> /// <param name="parent"> The parent drawer of created drawer. Can be null. </param> /// <param name="label"> The prefix label. </param> /// <param name="readOnly"> True if control should be read only. </param> /// <returns> The instance, ready to be used. </returns> public static MyDrawer Create(bool value, [CanBeNull]LinkedMemberInfo memberInfo, [CanBeNull]IParentDrawer parent, [CanBeNull]GUIContent label, bool readOnly) { MyDrawer result; if(!DrawerPool.TryGet(out result)) { result = new MyDrawer(); } result.Setup(value, typeof(bool), memberInfo, parent, label, readOnly); result.LateSetup(); return result; }
Implementing IDrawer
The IDrawer interface includes a large number of properties and methods that must be implemented, and as such, you usually don’t want to create new implementations of it from scratch unless absolutely necessary. Instead you should extend one of the included base classes, so that most of the functionality is already implemented for you. The base class you should extend depends on what type of content the drawer will represent: