GUI / Window Object
The global gui (also available as window) object provides application-level functionality and window control.
All examples use Risor v2 syntax with arrow functions.
Methods
SetContent
Sets the main content of the window.
window.SetContent(myWidget)
// Or using gui
window.SetContent(myWidget)Use cases: Display your UI, switch between views
SetStatus
Updates the status bar text.
window.SetStatus("Processing...")
window.SetStatus("Done!")Use cases: Progress updates, status messages, user feedback
Do
Execute a function on the main GUI thread. Required when updating GUI from background goroutines.
go(() => {
// Background work
let result = heavyComputation()
// Update GUI - must use window.Do()
window.Do(() => {
label.SetText(result)
})
})Important: Always use window.Do() when updating widgets from go() blocks.
Use cases: Updating UI from background tasks, thread-safe GUI updates
Resize
Resize the window to specific dimensions.
window.Resize(800, 600) // width, height in pixels
Use cases: Setting window size, responsive layouts
goto
Navigates to a different URL. Supports absolute and relative paths.
// Absolute URL
gui.goto("https://goto.global.iff.com/app/myapp")
// Relative path (same directory)
gui.goto("./other-app.risor")
gui.goto("other-app.risor")
// Navigate up one level
gui.goto("..")
// Navigate to subdirectory
gui.goto("./subdir/app.risor")Use cases: Navigation between apps, menu systems, workflow progression
OpenBrowser
Opens a URL in the system’s default web browser.
gui.OpenBrowser("https://example.com")
gui.OpenBrowser("https://goto.global.iff.com/docs")Use cases: External links, documentation, help pages
OpenExcel
Opens an Excel file in the default spreadsheet application.
gui.OpenExcel("/path/to/file.xlsx")
gui.OpenExcel("S:/data/report.xlsx")Use cases: Opening generated reports, viewing data files
OpenDir
Opens a directory in the system file explorer.
gui.OpenDir("/path/to/directory")
gui.OpenDir("S:/shared/folder")Use cases: Browse files, open containing folder
OnDropped
Handles file drag-and-drop events.
window.OnDropped(() => {
let paths = window.DroppedPaths
print("Dropped files:", paths)
paths.each(path => {
print("Processing:", path)
})
})Use cases: File upload, batch processing, drag-and-drop interfaces
CaptureStdout
Captures stdout and sends it to a callback function.
let log = widget.NewLog(100)
gui.CaptureStdout((line) => {
log.Append(line)
})
// Now all print() statements will appear in the log widget
print("This appears in the log")Use cases: Logging, debugging, capturing script output
Properties
GOOS
Operating system identifier.
if (gui.GOOS == "windows") {
// Windows-specific code
let path = "C:\\Users\\..."
} else if (gui.GOOS == "linux") {
// Linux-specific code
let path = "/home/..."
} else if (gui.GOOS == "darwin") {
// macOS-specific code
let path = "/Users/..."
}Values: "windows", "linux", "darwin" (macOS)
Status
Current status text (read/write).
gui.Status = "Loading..."
let currentStatus = gui.StatusCurrentBaseURL
Current script’s base URL. Useful for loading resources relative to the script.
// Load image from same directory as script
let logo = canvas.NewImageFromURI(gui.CurrentBaseURL + "logo.png")
// Navigate to sibling script
gui.goto(gui.CurrentBaseURL + "other-app.risor")DroppedPaths
List of dropped file paths (updated by OnDropped).
window.OnDropped(() => {
let files = window.DroppedPaths
files.each(file => {
print("Processing:", file)
})
})Common Patterns
Background Task with Progress
require("@gui")
let statusLabel = widget.NewLabel("Ready")
let progress = widget.NewProgressBarInfinite()
progress.Stop()
let btn = widget.NewButton("Start Task", () => {
statusLabel.SetText("Processing...")
progress.Start()
// Run in background
go(() => {
let result = heavyComputation()
// Update GUI on main thread
window.Do(() => {
progress.Stop()
statusLabel.SetText("Done: " + result)
})
})
})
window.SetContent(container.NewVBox(
btn,
progress,
statusLabel
))Platform-Specific Paths
let defaultPath = ""
if (gui.GOOS == "windows") {
defaultPath = "S:\\shared\\data"
} else {
defaultPath = "/mnt/shared/data"
}Resource Loading
// Load resources from same directory as script
let baseURL = gui.CurrentBaseURL
let logo = canvas.NewImageFromURI(baseURL + "logo.png")File Drop Handler
let fileLabel = widget.NewLabel("Drop files here")
window.OnDropped(() => {
let paths = window.DroppedPaths
fileLabel.SetText("Files: " + paths.join(", "))
paths.each(path => {
print("Processing:", path)
// Process each file
})
})
window.SetContent(container.NewCenter(fileLabel))Loading Indicator
window.SetStatus("Loading data...")
go(() => {
let data = loadData()
window.Do(() => {
window.SetStatus("Ready")
displayData(data)
})
})Threading Rules
Important: GUI widgets can only be updated from the main thread. When using go() for background tasks, always wrap GUI updates in window.Do():
// ✓ Correct
go(() => {
let result = backgroundWork()
window.Do(() => {
label.SetText(result)
})
})
// ✗ Wrong - will crash
go(() => {
let result = backgroundWork()
label.SetText(result) // Don't update GUI directly!
})Summary
The gui/window object provides:
- Window control: SetContent, Resize, SetStatus
- Navigation: goto, OpenBrowser, OpenExcel, OpenDir
- File handling: OnDropped, DroppedPaths
- Threading: Do() for thread-safe GUI updates
- System info: GOOS, CurrentBaseURL
- Output capture: CaptureStdout
Use window.Do() for all GUI updates from background goroutines.