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:
- the main type of the selected object
- 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.
- the main type renderer
- 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 component
s, 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
:
{
"contributions": {
"inspector": {
"section": {
"node": {
"CustomLabelComponent": "./dist/contributions/inspector/comp-label.js"
}
}
}
}
}
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:
'use strict';
type Selector<$> = { $: Record<keyof $, any | null> }
export const template = `
<!-- Elements to help submit data -->
<ui-prop type="dump" class="test"></ui-prop>
<!-- The actual rendered elements -->
<ui-label class="label"></ui-label>
<ui-input class="test-input"></ui-input>
`;
export const $ = {
label:'.label',
test: '.test',
testInput: '.test-input',
};
type PanelThis = Selector<typeof $> & { dump: any };
export function update(this: PanelThis, dump: any) {
this.dump = dump;
// Pass the 'dump' data to the prop element that helped submit the data
// Update the data on the input element responsible for 'input' and display
this.$.testInput.value = dump.value.label.value;
this.$.label.value = dump.value.label.name;
}
export function ready(this: PanelThis) {
// Listen for commit events on the input, update the dump data when the input commits data, and use prop to send change-dump events
this.$.testInput.addEventListener('confirm', () => {
this.dump.value.label.value = this.$.testInput.value;
this.$.test.dispatch('change-dump');
});
}
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 filestypescript
- TypeScript script filesprefab
- prefab filesfbx
- FBX filesmaterial
- material filesdirectory
- folderimage
- 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:
'use strict';
interface Asset {
displayName: string;
file: string;
imported: boolean;
importer: string;
invalid: boolean;
isDirectory: boolean;
library: {
[extname: string]: string;
};
name: string;
url: string;
uuid: string;
visible: boolean;
subAssets: {
[id: string]: Asset;
};
interface Meta {
files: string[];
imported: boolean;
importer: string;
[id: string]: Meta;
};
userData: {
[key: string]: any;
};
uuid: string;
ver: string;
}
type Selector<$> = { $: Record<keyof $, any | null> } & { dispatch(str: string): void, assetList: Asset[], metaList: Meta[] };
export const $ = {
'test': '.test',
};
export const template = `
<ui-prop>
<ui-label slot="label">Test</ui-label>
<ui-checkbox slot="content" class="test"></ui-checkbox>
</ui-prop>
`;
type PanelThis = Selector<typeof $>;
export function update(this: PanelThis, assetList: Asset[], metaList: Meta[]) {
this.assetList = assetList;
this.metaList = metaList;
this.$.test.value = metaList[0].userData.test || false;
};
export function ready(this: PanelThis) {
this.$.test.addEventListener('confirm', () => {
this.metaList.forEach((meta: any) => {
// Modify the data in the corresponding meta
meta.userData.test = !!this.$.test.value;
});
// 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
this.dispatch('change');
});
};
export function close(his: PanelThis, ) {
// 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.