{"id":177,"date":"2019-04-28T09:37:10","date_gmt":"2019-04-28T09:37:10","guid":{"rendered":"https:\/\/docs.sisus.co\/power-inspector\/?p=177"},"modified":"2019-11-16T10:13:23","modified_gmt":"2019-11-16T10:13:23","slug":"drawers-for-components","status":"publish","type":"post","link":"https:\/\/docs.sisus.co\/power-inspector\/extending-power-inspector\/drawers-for-components\/","title":{"rendered":"06. Drawers For Components"},"content":{"rendered":"<h1>Extending A Base Class<\/h1>\n<p>If you want to create a new drawer for a component, you can derive from one of two base classes that implements the <strong>IComponentDrawer<\/strong> interface.<\/p>\n<h2>1. ComponentDrawer<\/h2>\n<p>Extend <strong>ComponentDrawer <\/strong>if an <a href=\"https:\/\/docs.sisus.co\/power-inspector\/terminology\/editor\/\">Editor<\/a> <strong>is not<\/strong> used for drawing the class members of the Component.<\/p>\n<p>This gives you the most power to customize the drawer, and should be used when possible for the best results.<\/p>\n<pre><strong>Example: <\/strong>TransformDrawer<\/pre>\n<h2>2. CustomEditorComponentDrawer<\/h2>\n<p>Extend <strong>CustomEditorComponentDrawer<\/strong> if an <a href=\"https:\/\/docs.sisus.co\/power-inspector\/terminology\/editor\/\">Editor<\/a> <strong>is<\/strong> used for drawing the class members of the Component.<\/p>\n<p>In this case your options for customizing the drawer will be more limited, but you can still do things like add new header buttons or customize the context menu.<\/p>\n<p>This is mainly used when the target component has a <a href=\"https:\/\/docs.unity3d.com\/Manual\/editor-CustomEditors.html\">Custom Editor<\/a>.<\/p>\n<pre><strong>Example: <\/strong>CameraDrawer<\/pre>\n<h1>DrawerForComponent<\/h1>\n<p>For Power Inspector to know which Components should be represented by the drawer class you&#8217;ve created, you&#8217;ll need to add the DrawerForComponent attribute to the class.<\/p>\n<p>Here is an example of the attribute being used:<\/p>\n<pre>\/\/\/ &lt;summary&gt;\r\n\/\/\/ Handles drawing the Transform component inside the inspector view.\r\n\/\/\/ &lt;\/summary&gt;\r\n[Serializable, DrawerForComponent(typeof(Transform))]\r\npublic class TransformDrawer : ComponentDrawer<\/pre>\n<h1>Setup<\/h1>\n<p>When Power Inspector prepares a drawer for use inside an Inspector, it will call two methods inside the drawer class:<\/p>\n<ol>\n<li>First, it will call the <strong>SetupInterface<\/strong> method (defined in the IEditorlessComponentDrawer and ICustomEditorComponentDrawer interfaces).<\/li>\n<li>After that has finished, it will call the <strong>LateSetup<\/strong> method (defined in the base IDrawer interface).<\/li>\n<\/ol>\n<p>All drawer class also contain a <strong>Setup<\/strong> method. The only job of the <strong>SetupInterface <\/strong>method is to take the parameters provided by Power Inspector, and to convert them into a form that the main Setup method can accept, and then call that Setup method.<\/p>\n<p>You can <strong>override<\/strong> the Setup and LateSetup methods if you want to customize the setup phase.<\/p>\n<blockquote><p><strong>IMPORTANT NOTE<br \/>\n<\/strong>If you override Setup or LateSetup, remember to always also call <strong>base.Setup <\/strong>and <strong>base.LateSetup<\/strong><strong>! <\/strong><\/p><\/blockquote>\n<h1>DoGenerateMemberBuildList<\/h1>\n<p>You can override the DoGenerateMemberBuildList method to modify which <strong>class members<\/strong> of your component should be <strong>included<\/strong> inside the drawer.<\/p>\n<p>You do this by adding <strong>LinkedMemberInfos<\/strong> for the fields, properties and methods that you want to be built into a list called <strong>memberBuildList<\/strong>.<\/p>\n<p>LinkedMemberInfos are similar to the <strong><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.reflection.memberinfo\">MemberInfo class<\/a><\/strong> in .NET, and are used internally by drawers in Power Inspector to get and set the values of class members of different types. In fact, they usually work by wrapping a MemberInfo internally and layering functionality on top of it.<\/p>\n<p>You can use <strong>ParentDrawerUtility.GetMemberBuildList<\/strong> to generate the <strong>default member build list<\/strong> for your component, and then start editing it from there by adding or removing specific elements.<\/p>\n<pre>using System.Collections.Generic;\r\nusing Sisus;\r\nusing Sisus.Attributes;\r\n\r\n[DrawerForComponent(typeof(MyComponent))]\r\npublic class MyComponentDrawer : ComponentDrawer\r\n{\r\n\t\/\/\/ &lt;inheritdoc\/&gt;\r\n\tprotected override void DoGenerateMemberBuildList()\r\n\t{\r\n\t\t\/\/ Get ALL class members for the component by setting includeHidden to true.\r\n\t\t\/\/ Returned members will include non-public members, non-serialized members, fields, properties and methods.\r\n\t\tvar allClassMembers = new List&lt;LinkedMemberInfo&gt;();\r\n\t\tconst bool includeHidden = true;\r\n\t\tParentDrawerUtility.GetMemberBuildList(this, linkedMemberHierarchy, ref allClassMembers, includeHidden);\r\n\t\t\r\n\t\t\/\/ Add only the members you want shown to the member build list\r\n\t\tforeach(var linkedMember in allClassMembers)\r\n\t\t{\r\n\t\t\tswitch(linkedMember.Name)\r\n\t\t\t{\r\n\t\t\t\tcase \"MyField\":\r\n\t\t\t\tcase \"MyProperty\":\r\n\t\t\t\tcase \"MyMethod\":\r\n\t\t\t\t\tmemberBuildList.Add(linkedMember);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<h1>DoBuildMembers<\/h1>\n<p>You can also override DoBuildMembers to customize exactly what member drawers are built based on the memberBuildList that was previously generated by the DoGenerateMemberBuildList method.<\/p>\n<p>During the execution of this method all member drawers should be created and placed into the members array. If you want to add any member drawers that are not backed by a field, property or method in the component, you can do so here.<\/p>\n<p>You can use <strong>ParentDrawerUtility.BuildMembers<\/strong> to automatically generate members based on the contents of the memberBuildList, and this is what will happen if you do not override DoBuildMembers.<\/p>\n<pre>using UnityEngine;\r\nusing Sisus;\r\nusing Sisus.Attributes;\r\n\r\n[DrawerForComponent(typeof(MyComponent))]\r\npublic class MyComponentDrawer : ComponentDrawer\r\n{\r\n\t\/\/\/ &lt;inheritdoc\/&gt;\r\n\tprotected override void DoBuildMembers()\r\n\t{\r\n\t\t\/\/ build default member drawers\r\n\t\tbase.DoBuildMembers();\r\n\r\n\t\t\/\/ add a button member\r\n\t\tvar button = ButtonDrawer.Create(\"My Button\", OnMyButtonClicked, this);\r\n\t\tmembers = members.Add(button);\r\n\t}\r\n\r\n\tprivate void OnMyButtonClicked()\r\n\t{\r\n\t\tforeach(var target in targets)\r\n\t\t{\r\n\t\t\tDebug.Log(\"Clicked My Button on MyComponent target \" + target.name);\r\n\t\t}\r\n\t}\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Extending A Base Class If you want to create a new drawer for a component, you can derive from one of two base classes that implements the IComponentDrawer interface. 1. ComponentDrawer Extend ComponentDrawer if an Editor is not used for drawing the class members of the Component. This gives you the most power to customize ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"https:\/\/docs.sisus.co\/power-inspector\/extending-power-inspector\/drawers-for-components\/\" title=\"read more\">Read more<\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[10],"tags":[],"_links":{"self":[{"href":"https:\/\/docs.sisus.co\/power-inspector\/wp-json\/wp\/v2\/posts\/177"}],"collection":[{"href":"https:\/\/docs.sisus.co\/power-inspector\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/docs.sisus.co\/power-inspector\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/docs.sisus.co\/power-inspector\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/docs.sisus.co\/power-inspector\/wp-json\/wp\/v2\/comments?post=177"}],"version-history":[{"count":17,"href":"https:\/\/docs.sisus.co\/power-inspector\/wp-json\/wp\/v2\/posts\/177\/revisions"}],"predecessor-version":[{"id":1472,"href":"https:\/\/docs.sisus.co\/power-inspector\/wp-json\/wp\/v2\/posts\/177\/revisions\/1472"}],"wp:attachment":[{"href":"https:\/\/docs.sisus.co\/power-inspector\/wp-json\/wp\/v2\/media?parent=177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/docs.sisus.co\/power-inspector\/wp-json\/wp\/v2\/categories?post=177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/docs.sisus.co\/power-inspector\/wp-json\/wp\/v2\/tags?post=177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}