[Reserved for treeview and Tileview]
The treeview and gridview are very similar to listview.
Note! The function “is List item Expanded” crashes the editor.
1. Treeview - Getting Started
You setup a treeview the same way as a listview.
The point of a treeview is to have Items be “children” of other Items, like a tree!
You add children to an item in the function “On BP on Get Item Children 0”. This is a binding you find on the treeview events in the designer graph.
Once that binding is created, you will get a function with an in Item, and an array of items as children.
Again, if a entrywidget is created more than once for an instance, the engine will crash. This is very easily done when learning the treeview.
Using the ball actor in previous examples, I have added a bunch of mesh components which will be the children.
This is the basic setup I have created:
**Addendum: On BP Get Item Children needs to return an empty array if the cast fails, or this setup will not work.
Here, Ball 12 has been selected and the treeview expands it by getting all the children - children components in my case - and generating entrywidgets for them. Do note that the “On BP on Get Item Children 0” is also executed for each item - each child - that appears.
While there’s some basic formatting happening in the entrywidget - a textblock either has a > or V symbol, it could be done better.
- Some spacing for each child to better indicate what item they are children of.
- If an item does not have children, it really should not have either > or V symbol.
2. Treeview - Spacing [Backtracking through parent]
The spacing is set by adjusting the border left padding. The value depends on how deep in the hierarchy the item is. In this case we can find out the depth by calling a recursive function which gets the parent of each item.
3. Treeview - Expandable symbol
There are three possibilities with the expand symbol, in my case a simple > or V.
> means it can be expanded
V means it is expanded.
But if it can not be expanded - if it has no children - no symbol should be displayed.
So how do we determine that? Sure, you can cast the item to actor or scene component and get its children. But there’s already a similar example of that above, and also maybe you use some other method to determine if an item has children for the treeview. It might be better to let the treeview determine this.
Besides, while “On Item Selection Changed” updates for the entrywidget when scrolled into view, the event “On Item Expansion Changed” does not so we can not *rely *on that though it is needed.
The “On BP on Get Item Children 0” can be called manually to determine if the item is expandable or not.
The function “is List item Expanded” would have been useful but any use of it crashes the engine.
So we need to implement a custom way of remember the expanded items. I use a TSet of UObjects.
4. Treeview - Spacing [When getting the items children]
But not all treeviews will have items that actually inherit from one another. In that case you need to track the depth of the item. The tracking can be done in the “On BP on Get Item Children” function. By using a Tmap to store the item and its depth, we can query the depth of the parent and set the depth of its children as we enter those into the map. Then, as items are generated we can get the Item depth and set it for the widget.
Treeview - I don’t want the expansion changed!
Currenty, if an item has children and is clicked on, its expansion state will change. Following are a couple of solutions so that does not happen
5. Treeview - Expand only if Selected [revert expansion method]
Currently when an item is clicked, it will expand or collapse. What if we don’t want it to change its expanded state when we select it, but if we click it when it is selected, then it will change expansion state? Again, this is possible to achieve but requires our own implementation logic.
First, we must track which item is selected but can not use the treeview’s get selected item(s) function.
For the events that we will be using, the first thing that happens is that On Item Expansion Changed is called and after that On Item Selection Changed is called. However, printing the item that the expansion event provides, shows that the clicked item has already changed.
This means we can not use the treeview’s get selected item(s) function but can track the selected item and query the previous selected item during the expansion event.
The clicked item will change its expansion state, but we can revert the change by using the treeview function “Set Item Expansion”. However, that is going to trigger “On Item Expansion Changed” event again, so we need to track the revert logic so that the second event does not call the “Set Item Expansion” again.
** After some more experience, you may want to use an Item variable **Exclusively **to track the expanded state, instead of the “selected Item” reference which would be used for other things.
6. Treeview - Don’t change expansion [Override click method]
The entrywidget will internally tell the treeview that it was clicked on. Whether it was a border, an image or another user widget, it will detect the click.
Setting the entrywidget to hit test invisible is no good - we need to be able to click on the widget.
There is one widget that does not let the userwidget know it was clicked on: the button.
So below is an image of the entrywidget hierarchy. Logic will be that when the
-“Expand Button” is clicked, the expansion of the item is changed- collapses if expanded, expands if collapsed.
-“Select Button” is clicked, the item is selected.
-The border inside the “Select Button” is there for double clicks. That is done by selecting the border and under its events, create binding.
These click events calls event dispatchers.
Inside the widget that holds the treeview, we simply bind to the dispatchers during the “on entry generated” event.
The result is that the entry widget do not receive the clicked events, thus does not change the expanded state.
We manually change the expanded state depending on our needs.
In this case, the border with the text (which is held by a button) can be clicked on to only select the item, no change in expanded state.
The visible button can be clicked to change the expanded state only, without selecting the item.