Redscript
HomeGitHubDiscord
  • Home
  • Getting Started
    • Downloads
    • Setup for VSCode
    • Setup for JetBrains IDEs
    • How to start REDscripting
      • Step 1: Mod structure
      • Step 2: Finding the right class
  • Language
    • Intro
      • REDscript in 2 minutes
      • How to create a hook
        • Things to hook
    • Language Features
      • Intrinsics
      • Loops
      • Strings
      • Modules
      • Annotations
      • Conditional compilation
      • Configurable user hints
    • Built-in Types
    • Built-in Functions
      • Math
      • Random
      • Utilities
  • References and examples
    • Common Patterns
      • Safe downcasting
      • Class constructors
      • Hash maps
      • Heterogeneous array literals
      • Scriptable systems (singletons)
      • DelaySystem and DelayCallback
      • Generic callbacks
      • Persistence
    • Logging
    • UI Scripting
      • Logging Widget Trees
      • Popups
    • Vehicle system
    • Weapons
    • Codeware callbacks
      • Scriptables comparison
    • Libraries
    • Gameplay
      • Sleeping and Skipping Time
  • Help
    • Community
    • Troubleshooting
Powered by GitBook
On this page
  1. References and examples
  2. UI Scripting

Logging Widget Trees

PreviousUI ScriptingNextPopups

Last updated 1 year ago

Was this helpful?

CtrlK
  • Summary
  • Wait, that's not what I want!
  • Logging layer trees
  • Logging Widget Trees

Was this helpful?

Summary

Published: Mar 31 2024 by mana vortex Last documented update: Apr 15 2024 by mana vortex

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

Logging layer trees

You can find a list of existing UI layers on UI Scripting -> InkSystemLayers.

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

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

PrintLayerHierarchy(n"inkHUDLayer")

Logging Widget Trees

Big thanks to Rayshader for walking me through this with the patience of a saint!

You can add this code to your logs.reds file:

public static func LogWidgetTree(channel: CName, widget: wref<inkCompoundWidget>, opt props: Bool, opt indent: String) {
    let i = 0;

    if StrLen(indent) == 0 {
      LogChannel(channel, s"\(widget.GetName()) - \(widget.GetClassName())");
    }
    while i < widget.GetNumChildren() {
      let child: wref<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) {
        LogChannelTree(channel, compChild, props, s"\(indent)    ");
      }
      i += 1;
    }
  }