Table of contents
Playnote > Views
Each "screen" of the game displays some sort of tree of nested widgets. A view is a description of this tree structure. By customizing views, you can freely modify the layouts to move things around or split the space between them differently.
A basic view
Views are written in KDL 2.0, much like the manifest. Let's write a simplest possible view to showcase the syntax:
view "example" {
list {
slot "hello-world" type="text"
}
}
The outer element is a view, and then the name. Within it is a list, which is a layout widget. Layout widgets can be used freely to nest elements and define their layouts; their schemas are listed in the widget properties reference. Lastly, we have a slot. This is a placeholder, into which the game will place something concrete. Slot type is mandatory; this is the type of the widget that can be inserted into the slot.
Views and slots can't be created arbitrarily; they must match what the game expects. There is a list of views that should be in a theme, and each of these views must have the exact expected list of slots, each one with a specific type. example is not a real view, so this code would have no effect.
View files
A single .kdl file can contain multiple views, listed one after another at top-level:
view "one" {
// ...
}
view "two" {
// ...
}
Views are typically written into one or more files that are then linked from a manifest:
views.kdl:
view "example" {
// ...
}
theme.kdl:
theme "foobar" format=1 {
name "Foobar Theme"
// ... metadata ...
views "views.kdl"
}
Because it uses the same format, views works by splicing in the contents of the file. This means that it is possible to define views in the manifest itself!
theme "foobar" format=1 {
name "Foobar Theme"
// ... metadata ...
view "example" {
// ...
}
}
Of course, unless your theme is a small tweak to a view or two, it probably makes more sense to use separate files.
Classes
Both layout widgets and slots can have any number of classes attached. These classes can then be used to single out styleable widgets in stylesheet selectors.
view "example" {
list class="message-list" {
slot "heading" type="text" class="heading important"
slot "body" type="text" class="body"
}
}
Constructor arguments and layout properties
Some widgets' layouts require extra information to configure. This is handled by constructor arguments (on the widget itself) and layout properties (on children). Constructor arguments are typically required, while layout properties are optional. Unlike in CSS, these properties are part of the view structure rather than the stylesheet. You can set them like this:
view "example" {
column-grid columns=4 {
slot "wide" type="text" column-width=3
slot "narrow" type="text" // defaults to 1
}
}
columns is a constructor argument valid on a column-grid. column-width is a layout property valid only on direct children of a column-grid. Here, the two slots are horizontally split 75% to 25%.
Which layout properties are valid depends on the types of widgets involved. The complete list is in the reference.