Definitions
Tuesday, June 11, 2024
A definition is a set of data that defines the hierarchy and default values of definable widgets.
For Nebula: Definitions should only be editable when Developer Mode is enabled! Otherwise, regular users should be able to override definition values by creating styles!
Storage
Definitions should be stored as JSON files in the following directory:
...\AppData\Local\Layers\Definitions\
A Layers application should install its definitions and the definitions of any dependencies. A collection of definitions should be contained within a directory labeled with the name of the app/lib that the definition collection represents, along with the name of the publisher, placed within parentheses. There should also be a subdirectory labeled with the version tag of the app/lib since data structure can change between different versions. The following is an example:
...\Definitions\Nebula (The Layers Project)\0.1.0\
JSON Structure
Layers definitions should support inheritance in their file structure. This is an important aspect to minimize repeating code and file sizes. There will be a number of mechanisms in place to ensure that definitions only need to define the exact changes from its inherited data and nothing more.
The name of a definition file is up to the developer.
Aliases
Since a definition will be able to inherit another definition from a different library, and the path names for those definitions can be quite long given that they contain the library's publisher and version tag, it is useful to be able to define aliases for those path names.
A set of aliases should be definable in a file alongside the definitions that will use it. The aliases file should be labeled as follows:
_aliases.json
The following is an example of what the file could contain:
{
"QLayers": "QLayers (The Layers Project)/0.2.0"
}
The definition files adjacent to the above _aliases.json file would be able to use QLayers by itself without repeatedly including the publisher and version labels.
Inheritance
Inheritance will allow one definition to inherit another, including those from other libraries.
There will be two ways to set up inheritance. If the deriving definition does not change anything from the base definition, then its inheritance can be defined within the definition file like the following:
"Maximize Button": "titlebarbutton.json"
In the above, Maximize Button inherits the definition within titlebarbutton.json by pairing directly to the file path.
If the deriving definition changes values from the base definition, which means it needs to be structured as a JSON object, then the inheritance needs to be defined within that JSON object. This will be done by pairing _include with the path name of the definition being inherited. The following is an example:
"Main Window": {
"_include": "QLayers/qlwidget.json",
"attributes": {
// Overridden attribute values here
},
"children": {
// Overridden child values here
}
}
In the above, Main Window inherits the definition within QLayers/qlwidget.json, and then any values specific to the Main Window are defined within the same JSON object.
Attribute Values and Links
The following is an example of how a couple attributes might be defined:
"Main Window": {
"_include": "QLayers/qlwidget.json",
"attributes": {
"Border.Fill": "L:Theme/Gradient",
"Border.Thickness": 8,
// ...
},
// ...
}
In the above, Border.Fill and Border.Thickness, originally defined in QLayers/qlwidget.json, are overridden by the Main Window definition.
The Border.Thickness attribute is given the value of 8. An attribute value can be either a number, color, or gradient. (More value types will likely be supported in the future)
The Border.Fill attribute is given a string beginning with L: which indicates a link to another attribute, Theme/Gradient. Attributes with paths beginning with Theme are defined by the active theme.
Multiple links can be defined using an array labeled links, like the following example:
"Box": {
"attributes": {
"Fill": {
"links": [
"L:../Fill",
"L:Theme/Primary"
]
},
// ...
}
}
In this example, the Box's Fill attribute contains multiple links. When multiple links are defined, the attribute linker will attempt to link in the order that the attribute paths appear in the array, stopping at the first successful link. Given the above example, the linker will try to link Fill to a parent Fill, and if there is no parent, it will link to the Theme/Primary attribute instead.