Custom Inspector Panel

    The Inspector panel, the module in Cocos Creator that displays the currently selected state, provides some basic extension capabilities.

    In Inspector panel, two levels of data are defined:

    1. the main type of the selected object
    2. the sub-data types contained in the content when rendering the content of the main type

    When a node or an asset is selected in the Hierarchy/Assets Panel, Cocos Creator broadcasts the message that the object is selected. When the Inspector panel receives the message, it checks the type of the selected object, e.g. if the selected object is a node, then the type is .

    For both types, two types of renderers are allowed to be registered.

    1. the main type renderer
    2. When the main type renderer receives data to start rendering, it allows subtype renderers to be attached

    The selected object in the example is node, and node carries multiple components, so the main type is node and the subtype is component.

    After the Inspector receives the broadcast message for the selected object, it first determines the type, and then the Inspector takes the received data (the uuid of the object) and passes it to the node renderer, handing over the rendering privileges completely.

    And in the node renderer, the rendering privileges for that region are handed over to the subtype renderer when rendering to each component, according to its own implementation. For the most part, we don’t need to be concerned about this. Let’s take a look at a few common ways to customize it.

    First, create a new script component CustomLabelComponent.ts in the project and add a string property with the following content:

    Drag the component to the node and you will see an input box on the component.

    Create a new extension and register the following contributions.inspector information in the extension’s package.json:

    1. {
    2. "contributions": {
    3. "inspector": {
    4. "section": {
    5. "node": {
    6. "CustomLabelComponent": "./dist/contributions/inspector/comp-label.js"
    7. }
    8. }
    9. }
    10. }
    11. }

    Write a src/contributions/inspector/comp-label.ts file with the following contents:

    After compiling and refreshing the extension, we can see that the rendering of the CustomLabelComponent component has been taken over.

    Manual Rendering

    In the above auto-rendering example, we used a special ui-prop of type dump for rendering data submission, which allows us to quickly take over the rendering of the component, but if we face some extreme cases but it is difficult to handle some details, we can switch to manual rendering mode, the code is as follows:

    1. 'use strict';
    2. type Selector<$> = { $: Record<keyof $, any | null> }
    3. export const template = `
    4. <!-- Elements to help submit data -->
    5. <ui-prop type="dump" class="test"></ui-prop>
    6. <!-- The actual rendered elements -->
    7. <ui-label class="label"></ui-label>
    8. <ui-input class="test-input"></ui-input>
    9. `;
    10. export const $ = {
    11. label:'.label',
    12. test: '.test',
    13. testInput: '.test-input',
    14. };
    15. type PanelThis = Selector<typeof $> & { dump: any };
    16. export function update(this: PanelThis, dump: any) {
    17. this.dump = dump;
    18. // Pass the 'dump' data to the prop element that helped submit the data
    19. // Update the data on the input element responsible for 'input' and display
    20. this.$.testInput.value = dump.value.label.value;
    21. this.$.label.value = dump.value.label.name;
    22. }
    23. export function ready(this: PanelThis) {
    24. // Listen for commit events on the input, update the dump data when the input commits data, and use prop to send change-dump events
    25. this.$.testInput.addEventListener('confirm', () => {
    26. this.dump.value.label.value = this.$.testInput.value;
    27. this.$.test.dispatch('change-dump');
    28. });
    29. }

    Customizing Asset rendering

    When a file is selected in the Assets panel, the Inspector panel will display the important properties of the currently selected file, or we can customize the rendering if the default display does not meet the requirements.

    Add the contributions.section.asset field to package.json and define a custom rendering script for the corresponding asset type as follows:

    effect indicates that we want to customize the rendering of the asset inspector panel for the Cocos Effect (*.effect) file type. Common asset file types are as follows.

    • scene - Scene files
    • typescript - TypeScript script files
    • prefab - prefab files
    • fbx - FBX files
    • material - material files
    • directory - folder
    • image - image files

    You can get the type definition of the file by looking at the importer field in the *.meta corresponding to the file.

    Next, create a new src/contributions/inspector/asset-effect.ts script file in the extension directory and write the following code:

    1. 'use strict';
    2. interface Asset {
    3. displayName: string;
    4. file: string;
    5. imported: boolean;
    6. importer: string;
    7. invalid: boolean;
    8. isDirectory: boolean;
    9. library: {
    10. [extname: string]: string;
    11. };
    12. name: string;
    13. url: string;
    14. uuid: string;
    15. visible: boolean;
    16. subAssets: {
    17. [id: string]: Asset;
    18. };
    19. interface Meta {
    20. files: string[];
    21. imported: boolean;
    22. importer: string;
    23. [id: string]: Meta;
    24. };
    25. userData: {
    26. [key: string]: any;
    27. };
    28. uuid: string;
    29. ver: string;
    30. }
    31. type Selector<$> = { $: Record<keyof $, any | null> } & { dispatch(str: string): void, assetList: Asset[], metaList: Meta[] };
    32. export const $ = {
    33. 'test': '.test',
    34. };
    35. export const template = `
    36. <ui-prop>
    37. <ui-label slot="label">Test</ui-label>
    38. <ui-checkbox slot="content" class="test"></ui-checkbox>
    39. </ui-prop>
    40. `;
    41. type PanelThis = Selector<typeof $>;
    42. export function update(this: PanelThis, assetList: Asset[], metaList: Meta[]) {
    43. this.assetList = assetList;
    44. this.metaList = metaList;
    45. this.$.test.value = metaList[0].userData.test || false;
    46. };
    47. export function ready(this: PanelThis) {
    48. this.$.test.addEventListener('confirm', () => {
    49. this.metaList.forEach((meta: any) => {
    50. // Modify the data in the corresponding meta
    51. meta.userData.test = !!this.$.test.value;
    52. });
    53. // The Assets panel is modifying the meta file of the asset, not the dump data, so the event sent is not the same as the component property modification
    54. this.dispatch('change');
    55. });
    56. };
    57. export function close(his: PanelThis, ) {
    58. // TODO something

    After compiling and refreshing the extension, go back to the Cocos Creator editor interface, select one of the files, and you can find an additional Test checkbox at the bottom of the Inspector panel.

    Note: Multiple extensions register data side by side. If a Component/Asset already has a custom renderer, any custom renderers registered again will be appended to it. If a Component/Asset does not have a custom renderer built-in and uses the default renderer, then when the extension registers a custom renderer, it takes over the rendered content completely.