traverseDescendantsWithKeyDemo
@Sampled
fun traverseDescendantsWithKeyDemo() {
val customTraversableModifierNode = CustomTraversableModifierNode()
with(customTraversableModifierNode) {
traverseDescendants(traverseKey) {
if (it is CustomTraversableModifierNode) {
it.doSomethingWithDescendant()
}
// [traverseDescendants()] actually has three options:
// - ContinueTraversal
// - SkipSubtreeAndContinueTraversal - rarely used
// - CancelTraversal
// They are pretty self explanatory. Usually, you just want to continue or cancel the
// search. In some rare cases, you might want to skip the subtree but continue searching
// the tree.
TraverseDescendantsAction.ContinueTraversal
}
}
}
/**
* Simplified example of traverseDescendants. For a full featured sample, look below at
* [TraverseModifierDemo].
*/
traverseDescendantsDemo
@Sampled
fun traverseDescendantsDemo() {
val customTraversableModifierNode = CustomTraversableModifierNode()
with(customTraversableModifierNode) {
traverseDescendants {
// Because I use the existing key of the class, I can guarantee 'it' will be of the same
// type as the class, so I can call my functions directly.
it.doSomethingWithDescendant()
// [traverseDescendants()] actually has three options:
// - ContinueTraversal
// - SkipSubtreeAndContinueTraversal - rarely used
// - CancelTraversal
// They are pretty self explanatory. Usually, you just want to continue or cancel the
// search. In some rare cases, you might want to skip the subtree but continue searching
// the tree.
TraverseDescendantsAction.ContinueTraversal
}
}
}
/**
* Demonstrates how to use TraversableNode to traverse Modifier.Node ancestors, children, and
* descendants of the same key. This is done in 5 main steps:
*
* Step 1: Create a unique key for your TraversableNode. Step 2: Create a custom Modifier.Node class
* that implements TraversableNode. Step 3: Create a custom Modifier.Element class that uses that
* custom Modifier.Node. Step 4: Create an extension function on Modifier that uses the
* Modifier.Element. Step 5: Traverse the Modifier chain when you need to find your node(s).
*
* You can see the impact visually of traversing a particular direction from a TraversableNode by
* the TraversableNode(s) above or below changing their color to green. You can always reset the
* colors to try out a different traversal methods or nodes.
*
* Important Note: References are maintained to all the TraversableNode(s) in this UI, so we can
* directly call the traversable functions to see how they impact the tree. (We see this visually by
* the nodes changing color to green.) However, you most likely won't need a block parameter in your
* code to assign a reference. You will probably just trigger your traversals based on some other
* event (like a PointerEvent).
*
* See Compose Foundation's PointerHoverIconModifierNode or the DragAndDropNode implementations for
* real life examples. (PointerHoverIconModifierNode also skips subtrees.)
*
* You can also see more examples in TraversableModifierNodeTest (where we use multiple
* TraversableNodes with different keys).
*
* Simplified UI hierarchy for this demo (starts at first TraversableNode and ignores
* non-traversable Row, Spacers, and Text label composables along the way):
*
* Column Root (TraversableBackgroundModifierNode) ⤷ Column A (TraversableBackgroundModifierNode) ⤷
* Box A (TraversableBackgroundModifierNode) ⤷ Box B (NON-TRAVERSABLE Box) ⤷ Box C
* (TraversableBackgroundModifierNode)
*
* ⤷ Column B (TraversableBackgroundModifierNode) ⤷ Box D (NON-TRAVERSABLE Box) ⤷ Box E
* (TraversableBackgroundModifierNode) ⤷ Box F (NON-TRAVERSABLE Box)
*/