github.com/goki/ki@v1.1.11/walki/walki.go (about)

     1  // Copyright (c) 2020, The GoKi Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  /*
     6  Package walki provides basic tree walking functions for iterative traversal
     7  of the tree in up / down directions.  As compared to the core Func methods
     8  defined in ki package, these are for more dynamic, piecemeal processing.
     9  */
    10  package walki
    11  
    12  import (
    13  	"github.com/goki/ki/ki"
    14  )
    15  
    16  // Last returns the last node in the tree
    17  func Last(nd ki.Ki) ki.Ki {
    18  	var last ki.Ki
    19  	nd.FuncDownMeFirst(0, nd, func(k ki.Ki, level int, d interface{}) bool {
    20  		last = k
    21  		return ki.Continue
    22  	})
    23  	return last
    24  }
    25  
    26  // LastChild returns the last child under given node, or node itself if no children
    27  func LastChild(nd ki.Ki) ki.Ki {
    28  	if nd.HasChildren() {
    29  		ek, err := nd.Children().ElemFromEndTry(0)
    30  		if err == nil {
    31  			return LastChild(ek)
    32  		}
    33  	}
    34  	return nd
    35  }
    36  
    37  // Prev returns previous node in the tree -- nil if top
    38  func Prev(nd ki.Ki) ki.Ki {
    39  	if nd.Parent() == nil {
    40  		return nil
    41  	}
    42  	myidx, ok := nd.IndexInParent()
    43  	if ok && myidx > 0 {
    44  		nn := nd.Parent().Child(myidx - 1)
    45  		return LastChild(nn)
    46  	}
    47  	return nd.Parent()
    48  }
    49  
    50  // Next returns next node in the tree, nil if end
    51  func Next(nd ki.Ki) ki.Ki {
    52  	if !nd.HasChildren() {
    53  		return NextSibling(nd)
    54  	}
    55  	if nd.HasChildren() {
    56  		return nd.Child(0)
    57  	}
    58  	return nil
    59  }
    60  
    61  // NextSibling returns next sibling or nil if none
    62  func NextSibling(nd ki.Ki) ki.Ki {
    63  	if nd.Parent() == nil {
    64  		return nil
    65  	}
    66  	myidx, ok := nd.IndexInParent()
    67  	if ok {
    68  		if myidx < nd.Parent().NumChildren()-1 {
    69  			return nd.Parent().Child(myidx + 1)
    70  		}
    71  	}
    72  	return NextSibling(nd.Parent())
    73  }