JTML - Oinite12/balatro-modding-modules GitHub Wiki
JTML (Jimbo's Tabular Markup Lingo) is an alternate syntax for UIBox definitions that aims to reduce the semantic ambiguity and improve the readibility of code associated with UI. This file should be loaded before JTML elements are defined.
The development of this module and documentation would not be possible without the findings presented in Steamodded's UI Guide, from which most of the following information regarding UIBox analogs is obtained. I recommned reading the guide for more information on UI development.
It is recommended that the function generate_uibox_definition
be elevated to a global scope, either by adding the function to a global variable, or adding the function to a global table (i.e. G
). A guide can be found at the bottom of the file.
A JTML element is a table with the following values:
{
[1] = ...,
[2] = ...,
id = ...,
class = ...,
style = ...,
<attribute> = ...,
}
-
[1]
STRING - Element tag name. Should be one of the following values:- "root" (corresponds to
G.UIT.ROOT
) - "row" (corresponds to
G.UIT.R
) - "column" (corresponds to
G.UIT.C
) - "text" (corresponds to
G.UIT.T
) - "object" (corresponds to
G.UIT.O
) - "box" (corresponds to
G.UIT.B
) - "slider" (corresponds to
G.UIT.S
) - "input" (corresponds to
G.UIT.I
)
- "root" (corresponds to
-
[2]
TABLE optional - A table containing more JTML elements. (Analogous tonodes
on a UIBox definition table) -
id
STRING optional - An ID that, on the created UIBox,[UIBOX]:get_UIE_by_ID(<id>)
can use to target the node directly. -
class
STRING optional - A space-separated list of class names on a stylesheet. -
style
TABLE optional - The styling to apply to the JTML element. See the JTML styling section for more information. -
<attribtue>
(See following section for more information)
Attributes are additional properties of the JTML element that configure data handling and element behavior. They are analogous to UIBox config table properties. The following table is a list of element attributes:
JTML attrbiute | UIBox analog | Type | Usage |
---|---|---|---|
text |
text |
STRING | The string to display on "text" elements. |
object |
object |
Game object | The object to render on "object" elements. |
tooltip |
tooltip |
TABLE | The tooltip to display when the node is hovered over. Of the form {title = <STRING>, text = <TABLE>} where text contains strings. |
detailedtooltip |
detailed_tooltip |
TABLE | Similar to tooltip . |
instancetype |
instance_type |
STRING | The rendering layer that the node is drawn on. |
reftable |
ref_table |
TABLE | Used in conjunction with refvalue . |
refvalue |
ref_value |
STRING | A key on reftable whose value is passed to UI nodes or functions. |
ondraw |
func |
STRING | The name of a function in G.FUNCS that is called when the node is drawn. |
onclick |
button |
STRING | The name of a function in G.FUNCS that is called when the node is clicked. |
role |
role |
TABLE | In "object" elements, the relationship of the object to the UI. Of the form {role_type = <STRING>} where role_type should be one of "Major", "Minor", or "Glued". |
norole |
no_role |
BOOLEAN | In "object" elements, if true , the object has no explicit relation to the UI. |
language |
lang |
STRING | Value should be a localization code. |
instancetype
should be one of the folllowing values, from lowest to highest layer:
- "NODE"
- "MOVEABLE"
- "UIBOX"
- "CARDAREA"
- "CARD"
- "UI_BOX"
- "ALERT"
- POPUP
It is recommended that JTML element be formatted as follows:
{'element', id=..., class=..., ..., {
...
}}
Example with nested JTML elements:
{'root', id=..., class=..., ..., {
{'column', id=..., class=..., ..., {
{'row', id=..., class=..., ..., {
{'text', id=..., class=..., ...,},
{'text', id=..., class=..., ...,}
}},
{'row', id=..., class=..., ...,},
{'row', id=..., class=..., ...,}
}},
{'text', id=..., class=..., ...,}
}}
One way of thinking about this format is to regard {'element', ..., {
as the start tag of an HTML element (<element ...>
), while }}
is the end tag of an HTML element (</element>
):
<root id=... class=... ...>
<column id=... class=... ...>
<row id=... class=... ...>
<text id=... class=... ... />
<text id=... class=... ... />
</row>
<row id=... class=... ... />
<row id=... class=... ... />
</column>
<text id=... class=... ... />
</root>
Styling can be applied to JTML elements either in a stylesheet table or in-line (via the style
property) to specify visual characteristics of the element.
Style tables consist of property names as keys, and property values as values:
{
align = ...,
width = ...,
scale = ...,
}
These tables can be values of a JTML element's style
property, or added into a stylesheet table, which consists of element IDs/classes as keys, and style tables as values. Element IDs are prefixed with a hash (#element_id
) while element classes are prefixed with a period (.element_class
):
{
["#element_id"] = {},
[".element_class"] = {},
}
The following style properties are analogous to a UIBox config property:
JTML style property | UIBox analog | Type | Usage |
---|---|---|---|
align |
align |
STRING | How the element should be aligned relative to its parent. See this property's section for more information. |
minimumWidth minWidth
|
minw |
NUMBER | |
width |
w |
NUMBER | |
maxWidth |
maxw |
NUMBER | |
minimumHeight minHeight
|
minh |
NUMBER | |
height |
h |
NUMBER | |
maxHeight |
maxh |
NUMBER | |
padding |
padding |
NUMBER | The distance between the element's edges and its contents. |
roundness |
r |
NUMBER | How round the element's corners are. |
fillColour fillColor
|
colour |
TABLE ColourTable | The color of the element's background. Specifically, the value should be a G.C entry, or provided via HEX(<hexcode>) . |
noFill |
no_fill |
BOOLEAN | If true, the element's background is fully transparent. |
outlineWidth |
outline |
NUMBER | The thickness of the element's outline. |
outlineColour outlineColor
|
outline_colour |
TABLE ColourTable | The color of the element's outline. Specifically, the value should be a G.C entry, or provided via HEX(<hexcode>) . |
emboss |
emboss |
NUMBER | How much the element is "raised" out of its parent node. |
hover |
hover |
BOOLEAN | If true , the element will look like it is "hovering" over its parent. |
shadow |
shadow |
BOOLEAN | If true , a shadow will appear under the element, if hover = true . |
juice |
juice |
BOOLEAN | If true , the juice_up animation will be applied to the element when it is loaded in. |
onePress |
one_press |
??? | ??? |
focus |
focus_args |
TABLE | ??? |
scale |
scale |
NUMBER | On "text" elements, sets the size of the text. |
colour color
|
colour |
TABLE ColourTable | On "text" elements, sets the colour of the text. Specifically, the value should be a G.C entry, or provided via HEX(<hexcode>) . |
textOrientation |
vert |
STRING | On "text" elements, if set to "vertical", the text will be drawn sideways. |
lineEmboss |
line_emboss |
??? | ??? |
Align takes two types of strings:
- Two-character strings, where the first character dictates vertical alignment and is one of "t", "c", or "b", and the second character dictates horizontal alignment and is one of "l", "m", or "r".
- Strings of the form
<vert>-<hoz>
where<vert>
dictates vertical alignment and is one of "top", "center"/"middle", or "bottom", and<hoz>
dictates horizontal alignment and is one of "left", "middle"/"center", or "right". Either one of these formats are valid, however the second is recommended for readability.
If the same property is defined for an element via ID styling, class styling, or inline styling, the used value is the one of highest priority, as determined by the following list, from lowest to highest priority:
- ID styling
- Class styling - If multiple classes, classes increase priority from left to right
- Inline styling
For example, consider the following JTML element and stylesheet:
local element = {"text", id="example_text", class="normal_text blue_text"}
local stylesheet = {
[".normal_text"] = {colour = G.C.BLUE},
["#example_text"] = {colour = G.C.RED},
[".blue_text"] = {colour = G.C.GREEN},
}
element
will have colour G.C.GREEN
.
JTML elements are not valid values for UIBox definitions. Before using JTML elements in UIBox definitions, the elements need to be converted to UIBox definition tables via the generate_uibox_definition
function, which should be elevated to a global scope before this point.
generate_uibox_definition
takes a JTML element table, and a JTML stylesheet table, and returns a table formatted for UIBox definitions.
UIBox definition:
local element =
{n=G.UIT.ROOT, config = {align = "cm", minw = 1, minh = 0.3,padding = 0.15, r = 0.1, colour = G.C.CLEAR}, nodes={
{n=G.UIT.C, config={align = "cm", padding = 0.1, r = 0.1, colour = G.C.RED, outline = 1.5, outline_colour = G.C.WHITE, line_emboss = 1}, nodes={
{n=G.UIT.R, config={align = "cm", padding = 0}, nodes={
{n=G.UIT.R, config={align = "cm", padding = 0}, nodes={
{n=G.UIT.T, config={text = "example1", scale = text_scale*0.8, colour = G.C.UI.TEXT_LIGHT}}
}},
{n=G.UIT.R, config={align = "cm", padding = 0.1}, nodes={
{n=G.UIT.C, config={align = "cm", minh = 0.7, minw = 0.9, padding = 0.1, r = 0.1, hover = true, colour = G.C.ORANGE, button = "function1", shadow = true}, nodes={
{n=G.UIT.T, config={text = "example2", scale = text_scale*0.7, colour = G.C.UI.TEXT_LIGHT}}
}},
{n=G.UIT.C, config={align = "cm", minh = 0.7, minw = 0.9, padding = 0.1, r = 0.1, hover = true, colour = G.C.ORANGE, button = "function2", shadow = true}, nodes={
{n=G.UIT.T, config={text = "example3", scale = text_scale*0.7, colour = G.C.UI.TEXT_LIGHT}}
}}
}}
}}
}}
}}
JTML element/stylesheet:
local element =
{"root", class="group_root", {
{"column", class="other_actions", {
{"row", class="row_styles", {
{"row", class="row_styles", {
{"text", class="sorthand_text", text="example1"}
}},
{"row", class="row_styles", style={padding=0.1}, {
{"column", class="sorthand_button", onclick="function1", {
{"text", class="sorthand_button__text", text="example2"}
}},
{"column", class="sorthand_button", onclick="function2", {
{"text", class="sorthand_button__text", text="example3}
}},
}}
}}
}}
}}
local stylesheet = {
[".group_root"] = {
align = "center-middle",
minimumWidth = 1,
minimumHeight = 0.3,
padding = 0.15,
roundness = 0.1,
fillColour = G.C.CLEAR
},
[".other_actions"] = {
align = "center-middle",
padding = 0.1,
roundness = 0.1,
fillColour = G.C.RED,
outlineWidth = 1.5,
outlineColour = G.C.WHITE,
lineEmboss = 1
},
[".row_styles"] = {
align = "center-middle",
padding = 0
},
[".sorthand_text"] = {
scale = text_scale*0.8,
colour = G.C.UI.TEXT_LIGHT
},
[".sorthand_button"] = {
align = "center-middle",
minimumHeight = 0.7,
minimumWidth = 0.9,
padding = 0.1,
roundness = 0.1,
hover = true,
fillColour = G.C.ORANGE,
shadow = true
},
[".sorthand_button__text"] = {
scale = text_scale*0.7,
colour = G.C.UI.TEXT_LIGHT
}
}