Class ThemeFormat
# Limn theme
name = Ocean
dark = true
background = #0B1A24
surface = #11242F
primary = #4FD1C5
Here rather than in the editor module, so that an application can load a palette its designer built without the screen that built it anywhere in the build. That split is the whole point of the format: what crosses between authoring and wearing a theme is a value, and this is how it is written down.
parse(java.lang.String) and write(limn.components.Theme) are the pure pair: text in, text out, no disk, no
thread rules. load(Path) and load(InputStream) are the two lines above
them that an application actually calls, and they are here because the resource case is
not one line: a theme shipped inside a jar otherwise costs a try-with-resources, a null
check, readAllBytes and a charset, every time, in every application. There is no
save counterpart on purpose: writing is Files.writeString(path,
write(theme)) and nothing is hidden in it, and nobody writes back into a jar.
No asynchronous form, and none is owed. A palette is a configuration file of
about a kilobyte, read once, normally before there is a window to keep responsive. An
application loading one while a window is up (from a document, or a file the user just
chose) should still go through Ui.work, which is what ThemeEditorFiles
does; nothing here stops it, since load(java.nio.file.Path) is an ordinary blocking call.
What may be left out. name and dark are required: the mode
decides which built-in the missing tones are taken from, so a file without it would
mean two different palettes. Every colour is optional and falls back to the built-in
Theme.light() or Theme.dark(), which is what makes a four-line palette
a usable one, and so is cornerScale, which falls back to the shipped ramp.
What may not. A key that is not name, dark, cornerScale
or a Theme.Token.key() is an error rather than a shrug, and so is a repeated key: a
palette that silently ignored primaryHovor would be debugged by eye, in a
running application, against a tone that never moved.
-
Field Summary
Fields -
Method Summary
Modifier and TypeMethodDescriptionstatic Themeload(InputStream in) Reads a palette from a stream, the form a theme shipped inside a jar arrives in.static ThemeReads a palette from a file.static ThemeReads a palette back.static StringThe palette as text: a comment header,name,dark, then every tone inTheme.Tokenorder, one per line.
-
Field Details
-
EXTENSION
The conventional file extension, without the dot, for a file dialog's filter and for a resource name. Nothing enforces it; the parser reads whatever it is given.- See Also:
-
-
Method Details
-
load
Reads a palette from a file.Theme.setCurrent(ThemeFormat.load(Path.of("themes/ocean." + ThemeFormat.EXTENSION)));Blocking, and deliberately so; see the class documentation for when that is fine and when to wrap it in
Ui.work.- Throws:
IOException- if the file cannot be readIllegalArgumentException- if what it holds is not a palette, naming the line
-
load
Reads a palette from a stream, the form a theme shipped inside a jar arrives in.try (InputStream in = App.class.getResourceAsStream("/themes/ocean.limntheme")) { Theme.setCurrent(ThemeFormat.load(in)); }The stream is read to the end and left open, because it was opened by the caller: a method that closed a stream it did not open would break the try-with-resources above by making the close double.
- Throws:
IOException- if the stream cannot be readIllegalArgumentException- if what it holds is not a palette, naming the line
-
write
The palette as text: a comment header,name,dark, then every tone inTheme.Tokenorder, one per line.Deterministic and newline-terminated with
\non every platform: two writes of equal palettes produce equal strings, so a saved file can be diffed and a round trip can be asserted.- Throws:
IllegalArgumentException- if the name or the typeface family contains a line break or another control character. The format is one key per line and a value cannot span or end one: written as-is, such a name came back as a different name or as an extra key, silently, on the next load
-
parse
Reads a palette back. Blank lines are ignored, and so is any line whose first non-blank character is#; every other line iskey = value.A comment is a whole line and never the tail of one: a colour value begins with
#, and there is no spelling of "comment" that could also let that through.- Throws:
IllegalArgumentException- on any malformed, unknown, repeated or missing key, naming the line it was on; the message is meant to be shown to whoever wrote the file
-