Skip to content

Commit b057484

Browse files
committed
feat: Added support for Dark mode in Maven projects.
#3623
1 parent db58526 commit b057484

File tree

3 files changed

+121
-54
lines changed

3 files changed

+121
-54
lines changed

Ports/JavaSE/src/com/codename1/impl/javase/CSSWatcher.java

+65-13
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,13 @@
1414
import java.io.BufferedWriter;
1515
import java.io.File;
1616
import java.io.FileInputStream;
17-
import java.io.FileNotFoundException;
1817
import java.io.IOException;
1918
import java.io.InputStream;
2019
import java.io.InputStreamReader;
2120
import java.io.OutputStream;
2221
import java.io.OutputStreamWriter;
23-
import java.io.Writer;
2422
import java.net.ServerSocket;
2523
import java.net.Socket;
26-
import java.nio.file.Files;
2724
import java.util.ArrayList;
2825
import java.util.List;
2926
import java.util.Properties;
@@ -41,8 +38,15 @@ public class CSSWatcher implements Runnable {
4138
private Process childProcess;
4239
private boolean closing;
4340
private static final int MIN_DESIGNER_VERSION=6;
44-
41+
42+
private final String themePrefix;
43+
4544
public CSSWatcher() {
45+
this("");
46+
}
47+
48+
public CSSWatcher(String themePrefix) {
49+
this.themePrefix = themePrefix;
4650
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
4751

4852
@Override
@@ -170,29 +174,32 @@ public void run() {
170174

171175
}
172176
File javaBin = new File(System.getProperty("java.home"), "bin/java");
173-
final File srcFile = new File("css", "theme.css");
177+
final File srcFile = new File("css", themePrefix + "theme.css");
174178
String overrideInputs = System.getProperty("codename1.css.compiler.args.input", null);
175-
179+
if (overrideInputs != null) {
180+
overrideInputs = prefixInputs(themePrefix, overrideInputs);
181+
}
176182
if (!srcFile.exists() && overrideInputs == null) {
177183
//System.out.println("No theme.css file found. CSSWatcher canceled");
178184
return;
179185
} else {
180186
if (overrideInputs == null) {
181-
System.out.println("Found theme.css file. Watching for changes...");
187+
System.out.println("Found "+themePrefix+"theme.css file. Watching for changes...");
182188
} else {
183189
if (overrideInputs.trim().isEmpty()) {
184-
System.out.println("CSS file "+overrideInputs+" does not exist. Not activating CSS watcher");
190+
System.out.println("CSS file "+overrideInputs+" does not exist. Not activating CSS watcher for prefix " + themePrefix);
185191
return;
186192
}
187193
System.out.println("Watching CSS files for changes: ["+overrideInputs+"]");
188194
}
189195
}
190196
File resDir = JavaSEPort.getSourceResourcesDir();
191197

192-
File destFile = new File(resDir, "theme.res");
198+
File destFile = new File(resDir, themePrefix + "theme.res");
193199

194200
String overrideOutputs = System.getProperty("codename1.css.compiler.args.output", null);
195201
if (overrideOutputs != null) {
202+
overrideOutputs = prefixInputs(themePrefix, overrideOutputs);
196203
destFile = new File(overrideOutputs);
197204
}
198205
File userHome = new File(System.getProperty("user.home"));
@@ -228,7 +235,7 @@ public void run() {
228235
args.add("-watch");
229236
args.add("-Dprism.order=sw");
230237
}
231-
238+
System.out.println("Running CSS watch with args " + args);
232239

233240

234241
Process p = pb.start();
@@ -294,6 +301,9 @@ public void run() {
294301
Display.getInstance().callSerially(new Runnable() {
295302
@Override
296303
public void run() {
304+
if (!shouldRefresh()) {
305+
return;
306+
}
297307
try {
298308
if (fOverrideInputs != null) {
299309
System.out.println("CSS File "+fOverrideInputs+" has been updated. Reloading styles from "+fDestFile);
@@ -348,7 +358,49 @@ public void start() {
348358
watchThread.start();
349359
}
350360
}
351-
352-
353-
361+
362+
public static Iterable<String> scanForThemePrefixes() {
363+
File resourcesDir = getCSSSourceDirectory();
364+
List<String> prefixes = new ArrayList<>();
365+
int themeCssLen = "theme.css".length();
366+
if (resourcesDir != null && resourcesDir.isDirectory()) {
367+
for (File resourceFile : resourcesDir.listFiles()) {
368+
String fileName = resourceFile.getName();
369+
if (fileName.endsWith("theme.css")) {
370+
prefixes.add(fileName.substring(0, fileName.length() - themeCssLen));
371+
}
372+
}
373+
}
374+
return prefixes;
375+
}
376+
377+
private static File getCSSSourceDirectory() {
378+
File cssDir = new File(JavaSEPort.getCWD(), "src" + File.separator + "main" + File.separator + "css");
379+
if (cssDir.isDirectory()) return cssDir;
380+
return new File(JavaSEPort.getCWD(), "css");
381+
}
382+
383+
384+
private static String prefixInputs(String themePrefix, String inputs) {
385+
StringBuilder sb = new StringBuilder();
386+
for (String part : inputs.split(",")) {
387+
if (sb.length() > 0) {
388+
sb.append(",");
389+
}
390+
sb.append(prefixFile(themePrefix, new File(part)).getPath());
391+
}
392+
return sb.toString();
393+
}
394+
395+
private static File prefixFile(String themePrefix, File file) {
396+
return new File(file.getParentFile(), themePrefix + file.getName());
397+
}
398+
399+
private boolean shouldRefresh() {
400+
Display displayInstance = Display.getInstance();
401+
Boolean isDarkMode = displayInstance.isDarkMode();
402+
boolean isDarkModeBool = isDarkMode != null && isDarkMode;
403+
String localThemePrefix = themePrefix;
404+
return !isDarkModeBool && "".equals(localThemePrefix) || isDarkModeBool && "dark-".equals(localThemePrefix);
405+
}
354406
}

Ports/JavaSE/src/com/codename1/impl/javase/Executor.java

+12-9
Original file line numberDiff line numberDiff line change
@@ -274,15 +274,18 @@ public void run() {
274274
Display.init(null);
275275
if (CSSWatcher.isSupported()) {
276276
// Delay the starting of the CSS watcher to avoid compiling the CSS file while the theme is being loaded.
277-
Timer t = new Timer();
278-
TimerTask tt = new TimerTask() {
279-
@Override
280-
public void run() {
281-
CSSWatcher cssWatcher = new CSSWatcher();
282-
cssWatcher.start();
283-
}
284-
};
285-
t.schedule(tt, 2000);
277+
for (final String themePrefix : CSSWatcher.scanForThemePrefixes()) {
278+
Timer t = new Timer();
279+
TimerTask tt = new TimerTask() {
280+
@Override
281+
public void run() {
282+
System.out.println("Starting CSS Watcher for prefix " + themePrefix);
283+
CSSWatcher cssWatcher = new CSSWatcher(themePrefix);
284+
cssWatcher.start();
285+
}
286+
};
287+
t.schedule(tt, 2000);
288+
}
286289

287290
}
288291

maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CompileCSSMojo.java

+44-32
Original file line numberDiff line numberDiff line change
@@ -43,28 +43,59 @@
4343
requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME)
4444
public class CompileCSSMojo extends AbstractCN1Mojo {
4545

46+
4647
@Override
4748
protected void executeImpl() throws MojoExecutionException, MojoFailureException {
49+
File cssDirectory = findCSSDirectory();
50+
int themeCssLen = "theme.css".length();
51+
if (cssDirectory != null && cssDirectory.isDirectory()) {
52+
for (File file : cssDirectory.listFiles()) {
53+
String fileName = file.getName();
54+
if (fileName.endsWith("theme.css")) {
55+
executeImpl(fileName.substring(0, fileName.length() - themeCssLen));
56+
}
57+
}
58+
}
59+
}
60+
61+
/**
62+
* Gets the source CSS directory (src/main/css). The theme.css file should be inside this directory.
63+
* @return
64+
*/
65+
protected File findCSSDirectory() {
66+
for (String dir : project.getCompileSourceRoots()) {
67+
File dirFile = new File(dir);
68+
File cssSibling = new File(dirFile.getParentFile(), "css");
69+
File themeCss = new File(cssSibling, "theme.css");
70+
if (themeCss.exists()) {
71+
return cssSibling;
72+
}
73+
74+
}
75+
return null;
76+
}
77+
78+
private void executeImpl(String themePrefix) throws MojoExecutionException, MojoFailureException {
4879
if (!isCN1ProjectDir()) {
4980
return;
5081
}
5182
if (properties.getProperty("codename1.cssTheme", null) == null) {
5283
getLog().info("CSS themes not activated for this project. Skipping CSS compilation");
5384
return;
5485
}
55-
86+
5687
File cssDirectory = findCSSDirectory(); // src/main/css
5788
if (cssDirectory == null || !cssDirectory.exists()) {
5889
getLog().warn("CSS compilation skipped because no CSS theme was found");
5990
return;
6091
}
61-
File themeResOutput = new File(project.getBuild().getOutputDirectory() + File.separator + "theme.res");
92+
File themeResOutput = new File(project.getBuild().getOutputDirectory() + File.separator + themePrefix + "theme.res");
6293
// target/css
6394
File cssBuildDir = new File(project.getBuild().getDirectory() + File.separator + "css");
6495
cssBuildDir.mkdirs();
6596

6697
// target/css/theme.css - the merged CSS file
67-
File mergeFile = new File(cssBuildDir, "theme.css");
98+
File mergeFile = new File(cssBuildDir, themePrefix + "theme.css");
6899
mergeFile.getParentFile().mkdirs();
69100
try {
70101
if (themeResOutput.exists() && getCSSSourcesModificationTime() < themeResOutput.lastModified()) {
@@ -80,14 +111,14 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException
80111
// theme.css to the input list. (Codename One Library projects will include such an
81112
// artifact if they have CSS files).
82113
final StringBuilder inputs = new StringBuilder();
83-
114+
84115
project.getArtifacts().forEach(artifact->{
85116
if (artifact.hasClassifier() && "cn1css".equals(artifact.getClassifier())) {
86117
File zip = findArtifactFile(artifact);
87118
if (zip == null || !zip.exists()) {
88119
return;
89120
}
90-
121+
91122
File extracted = new File(zip.getParentFile(), zip.getName()+"-extracted");
92123
getLog().debug("Checking for extracted CSS bundle "+extracted);
93124
if (extracted.exists() && artifact.isSnapshot() && getLastModified(artifact) > extracted.lastModified()) {
@@ -112,7 +143,7 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException
112143
if (extractedCssDir.exists()) {
113144
// We expect that the cn1css artifact has a theme.css file at its root
114145
// If found, we add it to the list of inputs.
115-
File theme = new File(extractedCssDir, "theme.css");
146+
File theme = new File(extractedCssDir, themePrefix + "theme.css");
116147
if (theme.exists()) {
117148
if (inputs.length() > 0) {
118149
inputs.append(",");
@@ -130,18 +161,18 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException
130161
// The project's theme.css file is added to the input list last so that it will result in it
131162
// being last in the merged theme.css file (i.e. the application project CSS can override the
132163
// CSS in dependent libraries.
133-
File cssTheme = new File(cssDirectory, "theme.css");
164+
File cssTheme = new File(cssDirectory, themePrefix + "theme.css");
134165
if (cssTheme.exists()) {
135166
if (inputs.length() > 0) {
136167
inputs.append(",");
137168
}
138169
inputs.append(cssTheme.getAbsolutePath());
139170
} else {
140-
if (inputs.length() > 0) {
141-
throw new MojoFailureException("Cannot compile CSS for this project. The project does not include a theme.css file in "+cssTheme+", but it includes dependencies that require CSS. Please add a CSS file at "+cssTheme);
171+
if (themePrefix.isEmpty() && inputs.length() > 0) {
172+
throw new MojoFailureException("Cannot compile CSS for this project. The project does not include a "+themePrefix+"-theme.css file in "+cssTheme+", but it includes dependencies that require CSS. Please add a CSS file at "+cssTheme);
142173

143174
}
144-
getLog().info("Skipping CSS compilation because "+cssTheme+" does not exist");
175+
getLog().info("Skipping CSS compilation for because "+themePrefix + cssTheme+" does not exist");
145176
return;
146177
}
147178

@@ -164,36 +195,17 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException
164195
java.createArg().setValue("-css");
165196
java.createArg().setValue("-input");
166197
java.createArg().setValue(inputs.toString());
167-
198+
168199
java.createArg().setValue("-output");
169200
java.createArg().setFile(themeResOutput);
170-
201+
171202
java.createArg().setValue("-merge");
172203
java.createArg().setFile(mergeFile);
173204
int res = java.executeJava();
174205
if (res != 0) {
175-
throw new MojoExecutionException("An error occurred while compiling the CSS files. Inputs: "+inputs+", output: " + new File(project.getBuild().getOutputDirectory() + File.separator + "theme.res") +", merge file: "+mergeFile);
176-
}
177-
}
178-
179-
/**
180-
* Gets the source CSS directory (src/main/css). The theme.css file should be inside this directory.
181-
* @return
182-
*/
183-
protected File findCSSDirectory() {
184-
for (String dir : project.getCompileSourceRoots()) {
185-
File dirFile = new File(dir);
186-
File cssSibling = new File(dirFile.getParentFile(), "css");
187-
File themeCss = new File(cssSibling, "theme.css");
188-
if (themeCss.exists()) {
189-
return cssSibling;
190-
}
191-
206+
throw new MojoExecutionException("An error occurred while compiling the CSS files. Inputs: "+inputs+", output: " + new File(project.getBuild().getOutputDirectory() + File.separator + themePrefix + "theme.res") +", merge file: "+mergeFile);
192207
}
193-
return null;
194208
}
195-
196-
197209

198210

199211

0 commit comments

Comments
 (0)