fyne
fyne copied to clipboard
Tree Widget constantly calls IsBranch and ChildrenUIs
Checklist
- [X] I have searched the issue tracker for open issues that relate to the same problem, before opening a new one.
- [X] This issue only relates to a single bug. I will open new issues for any other problems.
Describe the bug
The default tree widget will constantly call functions like IsBranch and ChildrenUIs. This makes it only usable for a dictionary of strings, since if I use an actual tree structure, or a file tree, this makes the application slow down to a halt due to constantly walking the entire tree.
How to reproduce
- Create the widget from the example code
- Add it to a running app window
- Check the terminal output
Screenshots
No response
Example code
func New() *widget.Tree {
const root = "/"
var tree = &widget.Tree{
Root: root,
ChildUIDs: func(uid widget.TreeNodeID) (c []widget.TreeNodeID) {
log.Println("Tree-Get", uid)
return make([]widget.TreeNodeID, 0)
},
IsBranch: func(uid widget.TreeNodeID) (ok bool) {
log.Println("IsBranch", uid)
return false
},
CreateNode: func(branch bool) (o fyne.CanvasObject) {
log.Println("CreateNode")
return widget.NewLabel(root)
},
UpdateNode: func(uid widget.TreeNodeID, branch bool, node fyne.CanvasObject) {
node.(*widget.Label).SetText(uid)
},
}
return tree
}
Fyne version
2.3.5
Go compiler version
1.20
Operating system and version
Windows 10
Additional Information
This can be worked around by using a few caches, but the complexity of that doesn't make sense, plus, the documentation for widget.NewTree
suggests that it is a fast implementation.
// NewTree returns a new **performant** tree widget defined by the passed functions.
// childUIDs returns the child TreeNodeIDs of the given node.
// isBranch returns true if the given node is a branch, false if it is a leaf.
// create returns a new template object that can be cached.
// update is used to apply data at specified data location to the passed template CanvasObject.
//
// Since: 1.4
From my limited debugging, it seems that it's due to some underlying renderer calling the tree's MinSize() and/or Layout() which walks the entire tree, even when the entire tree has been walked once and hasn't changed due to any external factors (i.e resized, moved, interacted in any way, etc).
Slightly Offtopic: I noticed quite a few default widgets suffering from similar problems; having very specific use cases. Another example would be the FileDialog, which is a file selection tool that can only be used in a dialog. So if I'm writing an app where it only makes sense to have the file selection embedded on the window, I can't (which is what I'm doing now). I'm forced to roll out my own file selection from scratch basically.