> For the complete documentation index, see [llms.txt](https://wiki.redmodding.org/redscript/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.redmodding.org/redscript/references-and-examples/ui-scripting/logging-widget-trees.md).

# Logging Widget Trees

## Summary

**Published**: Mar 31 2024 by [mana vortex](mailto:undefined)\
**Last documented update**: Apr 15 2024 by [mana vortex](mailto:undefined)

This page will tell you how to log widget trees and layer trees.

### Wait, that's not what I want!

To learn more about logging, check [Logging](/redscript/references-and-examples/logging.md)

## Logging layer trees

You can find a list of existing UI layers on [UI Scripting](/redscript/references-and-examples/ui-scripting.md) -> [UI Scripting](/redscript/references-and-examples/ui-scripting.md#inksystemlayers).

To traverse a layer's children, you first need to get the corresponding layer's virtual window:

```swift
private static func PrintLayerHierarchy(layerName: CName) {
    let window = GameInstance.GetInkSystem().GetLayer(layerName).GetVirtualWindow();
    let rootWidget = window.GetWidgetByPathName(n"Root") as inkCanvas;
    // The function LogWidgetTree is defined below
    LogWidgetTree(n"DEBUG", rootWidget);
}

PrintLayerHierarchy(n"inkHUDLayer")
```

### Logging Widget Trees

{% hint style="info" %}
Big thanks to **Rayshader** for walking me through this with the patience of a saint!
{% endhint %}

You can add this code to your [`logs.reds`](/redscript/references-and-examples/logging.md) file:

<pre class="language-swift"><code class="lang-swift"><strong>public static func LogWidgetTree(channel: CName, widget: wref&#x3C;inkCompoundWidget>, opt props: Bool, opt indent: String) {
</strong>    let i = 0;

    if StrLen(indent) == 0 {
      LogChannel(channel, s"\(widget.GetName()) - \(widget.GetClassName())");
    }
    while i &#x3C; widget.GetNumChildren() {
      let child: wref&#x3C;inkWidget> = widget.GetWidget(i);
      let compChild = child as inkCompoundWidget;

      LogChannel(channel, s"\(indent)|-- \(child.GetName()) - \(child.GetClassName())");
      if props {
        let anchor = child.GetAnchor();
        let size = child.GetSize();
        let scale = child.GetScale();

        LogChannel(channel, s"\(indent){");
        LogChannel(channel, s"\(indent)  anchor: inkEAnchor.\(anchor)");
        LogChannel(channel, s"\(indent)  size: (\(size.X), \(size.Y))");
        LogChannel(channel, s"\(indent)  scale: (\(scale.X), \(scale.Y))");
        let wText = child as inkText;

        if IsDefined(wText) {
          LogChannel(channel, s"\(indent)  text: \"\(wText.GetText())\"");
          LogChannel(channel, s"\(indent)  fontSize: \"\(wText.GetFontSize())\"");
        }
        LogChannel(channel, s"\(indent)}");
      }
      if IsDefined(compChild) {
        LogWidgetTree(channel, compChild, props, s"\(indent)    ");
      }
      i += 1;
    }
  }
</code></pre>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://wiki.redmodding.org/redscript/references-and-examples/ui-scripting/logging-widget-trees.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
