Compile themes to BSS format
Every built-in theme is now available in both CSS and BSS formats.
This commit is contained in:
parent
d4d0526df0
commit
5f81fc2c5b
21
base/pom.xml
21
base/pom.xml
@ -58,6 +58,27 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<!-- compile themes to BSS -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>1.6.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile-to-bss</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>java</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>atlantafx.base.theme.ThemeCompiler</mainClass>
|
||||||
|
<arguments>
|
||||||
|
<argument>${project.build.directory}/classes/atlantafx/base/theme</argument>
|
||||||
|
</arguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package atlantafx.base.theme;
|
package atlantafx.base.theme;
|
||||||
|
|
||||||
import atlantafx.base.Preview;
|
import atlantafx.base.Preview;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A theme based on <a href="https://developer.apple.com/design/">IOS</a> color palette.
|
* A theme based on <a href="https://developer.apple.com/design/">IOS</a> color palette.
|
||||||
@ -30,6 +31,14 @@ public class CupertinoDark implements Theme {
|
|||||||
return "/atlantafx/base/theme/cupertino-dark.css";
|
return "/atlantafx/base/theme/cupertino-dark.css";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getUserAgentStylesheetBSS() {
|
||||||
|
return "/atlantafx/base/theme/cupertino-dark.bss";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -30,6 +30,14 @@ public class CupertinoLight implements Theme {
|
|||||||
return "/atlantafx/base/theme/cupertino-light.css";
|
return "/atlantafx/base/theme/cupertino-light.css";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getUserAgentStylesheetBSS() {
|
||||||
|
return "/atlantafx/base/theme/cupertino-light.bss";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -30,6 +30,14 @@ public class Dracula implements Theme {
|
|||||||
return "/atlantafx/base/theme/dracula.css";
|
return "/atlantafx/base/theme/dracula.css";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getUserAgentStylesheetBSS() {
|
||||||
|
return "/atlantafx/base/theme/dracula.bss";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -27,6 +27,14 @@ public final class NordDark implements Theme {
|
|||||||
return "/atlantafx/base/theme/nord-dark.css";
|
return "/atlantafx/base/theme/nord-dark.css";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getUserAgentStylesheetBSS() {
|
||||||
|
return "/atlantafx/base/theme/nord-dark.bss";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -27,6 +27,14 @@ public final class NordLight implements Theme {
|
|||||||
return "/atlantafx/base/theme/nord-light.css";
|
return "/atlantafx/base/theme/nord-light.css";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getUserAgentStylesheetBSS() {
|
||||||
|
return "/atlantafx/base/theme/nord-light.bss";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -27,6 +27,14 @@ public final class PrimerDark implements Theme {
|
|||||||
return "/atlantafx/base/theme/primer-dark.css";
|
return "/atlantafx/base/theme/primer-dark.css";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getUserAgentStylesheetBSS() {
|
||||||
|
return "/atlantafx/base/theme/primer-dark.bss";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -27,6 +27,14 @@ public final class PrimerLight implements Theme {
|
|||||||
return "/atlantafx/base/theme/primer-light.css";
|
return "/atlantafx/base/theme/primer-light.css";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getUserAgentStylesheetBSS() {
|
||||||
|
return "/atlantafx/base/theme/primer-light.bss";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -6,6 +6,7 @@ import static javafx.application.Application.STYLESHEET_CASPIAN;
|
|||||||
import static javafx.application.Application.STYLESHEET_MODENA;
|
import static javafx.application.Application.STYLESHEET_MODENA;
|
||||||
|
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic theme interface.
|
* Basic theme interface.
|
||||||
@ -23,6 +24,14 @@ public interface Theme {
|
|||||||
*/
|
*/
|
||||||
String getUserAgentStylesheet();
|
String getUserAgentStylesheet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the path to the theme user-agent stylesheet in binary
|
||||||
|
* (BSS) format. See {@link Application#setUserAgentStylesheet(String)} for more info.
|
||||||
|
* All built-in themes are available in BSS format, but custom themes may not,
|
||||||
|
* hence the method may return null value.
|
||||||
|
*/
|
||||||
|
@Nullable String getUserAgentStylesheetBSS();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signifies whether the theme uses a light font on a dark background
|
* Signifies whether the theme uses a light font on a dark background
|
||||||
* or vise versa.
|
* or vise versa.
|
||||||
@ -52,6 +61,11 @@ public interface Theme {
|
|||||||
return userAgentStylesheet;
|
return userAgentStylesheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getUserAgentStylesheetBSS() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDarkMode() {
|
public boolean isDarkMode() {
|
||||||
return darkMode;
|
return darkMode;
|
||||||
|
85
base/src/main/java/atlantafx/base/theme/ThemeCompiler.java
Normal file
85
base/src/main/java/atlantafx/base/theme/ThemeCompiler.java
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
package atlantafx.base.theme;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import javafx.css.Stylesheet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lazy man CSS to BSS compiler wrapper.
|
||||||
|
*/
|
||||||
|
public class ThemeCompiler {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
if (args.length < 1) {
|
||||||
|
throw new IllegalArgumentException("You must provide the source directory path");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length > 1) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unexpected arguments were found: "
|
||||||
|
+ Arrays.toString(Arrays.copyOfRange(args, 1, args.length))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dir = Paths.get(args[0]);
|
||||||
|
new ThemeCompiler().convertToBinary(dir);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts all CSS files in the specified directory to BSS.
|
||||||
|
*
|
||||||
|
* @param dir the source directory to scan for CSS files
|
||||||
|
* @throws IOException to punish you for using Java
|
||||||
|
*/
|
||||||
|
public void convertToBinary(Path dir) throws IOException {
|
||||||
|
if (dir == null || !Files.exists(dir) || !Files.isDirectory(dir)) {
|
||||||
|
throw new IllegalArgumentException("Invalid directory: " + dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Stream<Path> stream = Files.list(dir)) {
|
||||||
|
stream.filter(f -> f.toString().endsWith(".css"))
|
||||||
|
.forEach(f -> {
|
||||||
|
try {
|
||||||
|
convertToBinary(f, f.resolveSibling(getFilename(f) + ".bss"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the specified CSS file to BSS. If no output file is given,
|
||||||
|
* then the input file name is used with an extension of 'bss'.
|
||||||
|
*
|
||||||
|
* @param in input file path
|
||||||
|
* @param out output file path
|
||||||
|
* @throws IOException to punish you for using Java
|
||||||
|
*/
|
||||||
|
public void convertToBinary(Path in, Path out) throws IOException {
|
||||||
|
if (in == null || out == null) {
|
||||||
|
throw new IllegalArgumentException("Both input and output files must be specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in.equals(out)) {
|
||||||
|
throw new IllegalArgumentException("Input file and output file cannot be the same.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Stylesheet.convertToBinary(in.toFile(), out.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFilename(Path f) {
|
||||||
|
String name = f.getFileName().toString();
|
||||||
|
return name.substring(0, name.lastIndexOf('.'));
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,7 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Theme} decorator to work around some JavaFX CSS limitations.
|
* The {@link Theme} decorator to work around some JavaFX CSS limitations.
|
||||||
@ -87,6 +88,11 @@ public final class SamplerTheme implements Theme {
|
|||||||
return IS_DEV_MODE ? DUMMY_STYLESHEET : getResource().toURI().toString();
|
return IS_DEV_MODE ? DUMMY_STYLESHEET : getResource().toURI().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getUserAgentStylesheetBSS() {
|
||||||
|
return theme.getUserAgentStylesheetBSS();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDarkMode() {
|
public boolean isDarkMode() {
|
||||||
return theme.isDarkMode();
|
return theme.isDarkMode();
|
||||||
|
Loading…
Reference in New Issue
Block a user