Extending PCUI TreeViewItem Component

Hi folks! I’m trying to extend the TreeViewItem or TreeView component so that I can include a label and boolean input for each item. But it looks like TreeView constructor is hardcoded to create a TreeViewItem for every child. Any suggestions on how I might be able to extend this to match something like the attached image?
image

@Elliott @kungfooman Any ideas on this one?

You could create a TreeView component and then append each TreeViewItem to the TreeView hierarchy yourself. Then before appending each TreeViewItem you could also add your own BooleanInput to that TreeViewItem’s dom.

1 Like

Thanks! I’ll give that a try.

I guess you just want to display all entities too with a button to enable/disable them. So you can just write a recursive function going over app.root, starting with an empty TreeView, and then add your custom TreeViewItem's with a function like:


export function newTreeViewItemGraphNode(graphNode: pc.GraphNode) {
  var treeViewItem = new pcui.TreeViewItem({
    text: graphNode.name,
    enabled: graphNode.enabled
  });
  // Link each other:
  graphNode.treeViewItem = treeViewItem;
  // @ts-ignore
  treeViewItem.entity = graphNode; // Maybe display Entity/GraphNode differently, since Entity has so much more functionality
    // @ts-ignore
  treeViewItem.graphNode = graphNode;
  var boolButton = newBooleanInput(graphNode.enabled);
    // @ts-ignore
  var container = treeViewItem.dom.children[0].ui;
  container.append(boolButton);
  boolButton.on('click', (event: MouseEvent) => {
    var value = boolButton.value;
    // Get every meshInstance in scene and check if its node is this node... so we can hide it, when we disable its graphNode
    // Ideally the graphNodes would have node.meshInstances, add in playcanvas-gltf?
    // TODO: Hiding a parent should hide all its children too
    // TODO: Cache meshInstances for large scenes?
    // TODO: put this all into enable/disable for functional programming
    getMeshInstances(app.root)
      .filter(meshInstance => meshInstance.node == graphNode)
      .forEach(meshInstance => meshInstance.visible = value);
    graphNode.enabled = value;
    // TODO: do not go into rename mode via double clicking (this doesn't work yet)
    event.preventDefault();
    event.stopPropagation();
  });
  return treeViewItem;
}

export function newBooleanInput(value: boolean = true) {
  return new pcui.BooleanInput({
    value
  });
}

Its a huge TODO fest, but shows how to just attach custom elements to the TreeViewItem and it works good enough for me.

It will look like:

image

Which is kinda ugly, I would prefer it like:

image

It may be just some CSS settings, but thats another TODO.

3 Likes