Fixed the logic for triggering a TreeView's "changed" callback, allowing it to be triggered for calls to SetCurrentNode(), too.

pull/836/head
Oliver 1 year ago
parent becbc92f00
commit 87723e5081

@ -274,6 +274,9 @@ type TreeView struct {
// The currently selected node or nil if no node is selected.
currentNode *TreeNode
// The last note that was selected or nil of there is no such node.
lastNode *TreeNode
// The movement to be performed during the call to Draw(), one of the
// constants defined above.
movement int
@ -346,8 +349,8 @@ func (t *TreeView) GetRoot() *TreeNode {
// selection will be changed to the top-most selectable and visible node.
//
// This function does NOT trigger the "changed" callback because the actual node
// that will be selected is not known until the tree is drawn. That is also when
// the "changed" callback will be triggered.
// that will be selected is not known until the tree is drawn. Triggering the
// "changed" callback is thus deferred until the next call to [TreeView.Draw].
func (t *TreeView) SetCurrentNode(node *TreeNode) *TreeView {
t.currentNode = node
return t
@ -404,8 +407,8 @@ func (t *TreeView) SetGraphicsColor(color tcell.Color) *TreeView {
return t
}
// SetChangedFunc sets the function which is called when the user navigates to
// a new tree node.
// SetChangedFunc sets the function which is called when the currently selected
// node changes, for example when the user navigates to a new tree node.
func (t *TreeView) SetChangedFunc(handler func(node *TreeNode)) *TreeView {
t.changed = handler
return t
@ -458,9 +461,9 @@ func (t *TreeView) Move(offset int) *TreeView {
}
// process builds the visible tree, populates the "nodes" slice, and processes
// pending movement actions. Set "drawingAfter" to true if you know that [Draw]
// will be called immediately after this function (to avoid having [Draw] call
// it again).
// pending movement actions. Set "drawingAfter" to true if you know that
// [TreeView.Draw] will be called immediately after this function (to avoid
// having [TreeView.Draw] call it again).
func (t *TreeView) process(drawingAfter bool) {
t.stableNodes = drawingAfter
_, _, _, height := t.GetInnerRect()
@ -544,26 +547,25 @@ func (t *TreeView) process(drawingAfter bool) {
// Process selection. (Also trigger events if necessary.)
if selectedIndex >= 0 {
// Move the selection.
newSelectedIndex := selectedIndex
switch t.movement {
case treeMove:
for t.step < 0 { // Going up.
index := newSelectedIndex
index := selectedIndex
for index > 0 {
index--
if t.nodes[index].selectable {
newSelectedIndex = index
selectedIndex = index
break
}
}
t.step++
}
for t.step > 0 { // Going down.
index := newSelectedIndex
index := selectedIndex
for index < len(t.nodes)-1 {
index++
if t.nodes[index].selectable {
newSelectedIndex = index
selectedIndex = index
break
}
}
@ -571,26 +573,20 @@ func (t *TreeView) process(drawingAfter bool) {
}
case treeParent:
if parentSelectedIndex >= 0 {
newSelectedIndex = parentSelectedIndex
selectedIndex = parentSelectedIndex
}
case treeChild:
index := newSelectedIndex
index := selectedIndex
for index < len(t.nodes)-1 {
index++
if t.nodes[index].selectable && t.nodes[index].parent == t.nodes[selectedIndex] {
newSelectedIndex = index
selectedIndex = index
}
}
}
t.step = 0
t.currentNode = t.nodes[newSelectedIndex]
if newSelectedIndex != selectedIndex {
t.movement = treeNone
if t.changed != nil {
t.changed(t.currentNode)
}
}
selectedIndex = newSelectedIndex
t.currentNode = t.nodes[selectedIndex]
t.movement = treeNone
// Move selection into viewport.
if t.movement != treeScroll {
@ -616,6 +612,12 @@ func (t *TreeView) process(drawingAfter bool) {
t.currentNode = nil
}
}
// Trigger "changed" callback.
if t.changed != nil && t.currentNode != nil && t.currentNode != t.lastNode {
t.changed(t.currentNode)
}
t.lastNode = t.currentNode
}
// Draw draws this primitive onto the screen.

Loading…
Cancel
Save