Customizing the Inspector

The inspector window shows the current selection’s properties, in our case called object fields. In the inspector window there can be shown many types of object properties, starting from scene objects, assets, editor preferences, etc. If many different types are selected (for example some assets in the asset browser and some scene objects) the Inspector will show a list of those types and their count:

../../../_images/multi_type_selection.png

The editor.selection member is a table of type name and an array of (usually) numerical IDs for the selected type. As an example, if we selected few scene objects AND an asset in the asset browser, editor.selection will be made of:

editor.selection.object will be an id array like: {122,334,566,44} editor.selection.asset will be an id array like: {2,4,53,3442,3434,1566,244}

When editor.selection is {}, there is no selection in the editor.

Instances and Locking

The inspector can have many instances, created with editor.addInspectorInstance() or pushing the New Inspector button in the inspector window. Also one can lock the inspector to the current selection, and if the editor selection changes, this will not affect the locked inspector instances, they will keep showing their locked selection fields.

Selection Type Handlers

For the inspector to know what editing UI to show for the current editor selection, the user must call editor.registerInspectorTypeHandler(typeName, guiCallback) so that when it has a type having a non empty selection, it will call that specific guiCallback to draw the inspector window’s UI. By default there is already a handler registered for "object" which draws a field values editor for the selected scene objects.

If a user extension wants to render UI in the inspector for special selections, it will call the register function in the hook named onEditorInitialized which is called right after all extensions were loaded.

Customize inspector UI
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
-- this is the guiCallback function which will be called to render inspector UI
local function assetInspectorGui(inspectorInfo)
  local selectedAssets
  -- if this inspector instance is not a locked one (not locked on a specific selection)
  -- then use the current editor selection
  if inspectorInfo.selection == nil then
    selectedAssets = editor.selection.asset
  else
  -- else use the locked selection from the given inspector info table
    selectedAssets = inspectorInfo.selection.asset
  end
  -- just show the list of selected assets
  for i = 1, #selectedAssets do
    ui_imgui.Text(selectedAssets[i])
  end
end

-- when the editor is initialized, this will be called after all extensions were loaded
local function onEditorInitialized()
  -- register out special selection type handler
  -- first is the name if our selection type
  -- second is the callback to be invoked when there is a valid editor.selection.asset array of selected assets
  editor.registerInspectorTypeHandler("asset", assetInspectorGui)
end

M.onEditorInitialized = onEditorInitialized
M.onExtensionLoaded = onExtensionLoaded

Inspector Header UI

If you want to show some specific tools/widgets depending on the current selection, you can add the onEditorInspectorHeaderGui to your extension’s M module. The function will receive an argument which is the inspectorInfo inspector instance info, having a selection member which is nil or the locked selection of that inspector instance. It will be called right after the call to render inspector widgets, basically any UI you emit in this function will be at the top of the Inspector window, independent of any inspector selection type. You can check the editor.selection to see if there is a type and an object of that type valid, so you can for example show some paint buttons for when a terrain is selected. If the current selection is of interest, just return from your function.

Customize inspector header UI
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- the function to show our terrain paint gui
local function showTerrainPaintGui(objectId)
        local obj = scenetree.findObjectById(objectId)
        -- if this object is a terrain block, then yes, show the terrain paint gui
        if obj:getClassName() == "TerrainBlock" then
                ui_imgui.Button("Raise height")
        end
end

-- called at the start of inspector window widget drawing
local function onEditorInspectorHeaderGui(inspectorInfo)
        -- if there is a locked selection in this inspector instance, use it
        if inspectorInfo.selection and #inspectorInfo.selection.object then
                showTerrainPaintGui(inspectorInfo.selection.object[1])
        -- if there is a current selection in this inspector instance, use it
        elseif editor.selection and #editor.selection.object then
                showTerrainPaintGui(editor.selection.object[1])
        end
end

-- make sure we're called by extensions.hook
M.onEditorInspectorHeaderGui = onEditorInspectorHeaderGui