mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +00:00
Implement automatic theme detection
This commit is contained in:
parent
06cb31bf55
commit
441226855f
10 changed files with 144 additions and 50 deletions
|
@ -24,6 +24,7 @@ apply from: "$rootDir/gradle/gradle_scripts/lombok.gradle"
|
|||
apply from: "$projectDir/gradle_scripts/github-api.gradle"
|
||||
apply from: "$projectDir/gradle_scripts/flexmark.gradle"
|
||||
apply from: "$rootDir/gradle/gradle_scripts/picocli.gradle"
|
||||
apply from: "$rootDir/gradle/gradle_scripts/versioncompare.gradle"
|
||||
|
||||
configurations {
|
||||
implementation.extendsFrom(dep)
|
||||
|
@ -38,8 +39,8 @@ dependencies {
|
|||
compileOnly 'org.junit.jupiter:junit-jupiter-api:5.9.0'
|
||||
compileOnly 'org.junit.jupiter:junit-jupiter-params:5.9.0'
|
||||
|
||||
implementation 'net.java.dev.jna:jna-jpms:5.12.1'
|
||||
implementation 'net.java.dev.jna:jna-platform-jpms:5.12.1'
|
||||
implementation 'net.java.dev.jna:jna-jpms:5.13.0'
|
||||
implementation 'net.java.dev.jna:jna-platform-jpms:5.13.0'
|
||||
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "2.13.0"
|
||||
implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-parameter-names', version: "2.13.0"
|
||||
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: "2.13.0"
|
||||
|
@ -56,7 +57,14 @@ dependencies {
|
|||
implementation 'com.jfoenix:jfoenix:9.0.10'
|
||||
implementation 'org.controlsfx:controlsfx:11.1.1'
|
||||
implementation 'net.synedra:validatorfx:0.3.1'
|
||||
implementation 'io.github.mkpaz:atlantafx-base:1.2.0'
|
||||
implementation name: 'atlantafx-base-1.2.1'
|
||||
implementation name: 'atlantafx-styles-1.2.1'
|
||||
implementation name: 'jSystemThemeDetector-3.8'
|
||||
implementation group: 'com.github.oshi', name: 'oshi-core-java11', version: '6.4.2'
|
||||
implementation 'org.jetbrains:annotations:24.0.1'
|
||||
implementation ('de.jangassen:jfa:1.2.0') {
|
||||
exclude group: 'net.java.dev.jna', module: 'jna'
|
||||
}
|
||||
}
|
||||
|
||||
apply from: "$rootDir/gradle/gradle_scripts/junit.gradle"
|
||||
|
|
|
@ -1,17 +1,9 @@
|
|||
package io.xpipe.app.core;
|
||||
|
||||
import atlantafx.base.theme.NordDark;
|
||||
import atlantafx.base.theme.NordLight;
|
||||
import atlantafx.base.theme.PrimerDark;
|
||||
import atlantafx.base.theme.PrimerLight;
|
||||
import io.xpipe.app.ext.PrefsChoiceValue;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import javafx.application.Application;
|
||||
import javafx.scene.Scene;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
|
@ -36,9 +28,6 @@ public class AppStyle {
|
|||
loadStylesheets();
|
||||
|
||||
if (AppPrefs.get() != null) {
|
||||
AppPrefs.get().theme.addListener((c, o, n) -> {
|
||||
changeTheme(o, n);
|
||||
});
|
||||
AppPrefs.get().useSystemFont.addListener((c, o, n) -> {
|
||||
changeFontUsage(n);
|
||||
});
|
||||
|
@ -78,12 +67,6 @@ public class AppStyle {
|
|||
}
|
||||
}
|
||||
|
||||
private static void changeTheme(Theme oldTheme, Theme newTheme) {
|
||||
scenes.forEach(scene -> {
|
||||
Application.setUserAgentStylesheet(newTheme.getTheme().getUserAgentStylesheet());
|
||||
});
|
||||
}
|
||||
|
||||
private static void changeFontUsage(boolean use) {
|
||||
if (!use) {
|
||||
scenes.forEach(scene -> {
|
||||
|
@ -106,10 +89,6 @@ public class AppStyle {
|
|||
}
|
||||
|
||||
public static void addStylesheets(Scene scene) {
|
||||
var t = AppPrefs.get() != null ? AppPrefs.get().theme.getValue() : Theme.LIGHT;
|
||||
Application.setUserAgentStylesheet(t.getTheme().getUserAgentStylesheet());
|
||||
TrackEvent.debug("Set theme " + t.getId() + " for scene");
|
||||
|
||||
if (AppPrefs.get() != null && !AppPrefs.get().useSystemFont.get()) {
|
||||
scene.getStylesheets().add(FONT_CONTENTS);
|
||||
}
|
||||
|
@ -122,21 +101,4 @@ public class AppStyle {
|
|||
scenes.add(scene);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum Theme implements PrefsChoiceValue {
|
||||
LIGHT("light", new PrimerLight()),
|
||||
DARK("dark", new PrimerDark()),
|
||||
NORD_LIGHT("nordLight", new NordLight()),
|
||||
NORD_DARK("nordDark", new NordDark());
|
||||
// DARK("dark");
|
||||
|
||||
private final String id;
|
||||
private final atlantafx.base.theme.Theme theme;
|
||||
|
||||
@Override
|
||||
public String toTranslatedString() {
|
||||
return theme.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
103
app/src/main/java/io/xpipe/app/core/AppTheme.java
Normal file
103
app/src/main/java/io/xpipe/app/core/AppTheme.java
Normal file
|
@ -0,0 +1,103 @@
|
|||
package io.xpipe.app.core;
|
||||
|
||||
import atlantafx.base.theme.*;
|
||||
import com.jthemedetecor.OsThemeDetector;
|
||||
import io.xpipe.app.ext.PrefsChoiceValue;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import javafx.application.Application;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
public class AppTheme {
|
||||
|
||||
public static void init() {
|
||||
if (AppPrefs.get() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
OsThemeDetector detector = OsThemeDetector.getDetector();
|
||||
if (AppPrefs.get().theme.getValue() == null) {
|
||||
try {
|
||||
setDefault(detector.isDark());
|
||||
} catch (Throwable ex) {
|
||||
ErrorEvent.fromThrowable(ex).omit().handle();
|
||||
setDefault(false);
|
||||
}
|
||||
}
|
||||
var t = AppPrefs.get().theme.getValue();
|
||||
|
||||
Application.setUserAgentStylesheet(t.getTheme().getUserAgentStylesheet());
|
||||
TrackEvent.debug("Set theme " + t.getId() + " for scene");
|
||||
|
||||
detector.registerListener(dark -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
if (dark && !AppPrefs.get().theme.getValue().getTheme().isDarkMode()) {
|
||||
AppPrefs.get().theme.setValue(Theme.getDefaultDarkTheme());
|
||||
}
|
||||
|
||||
if (!dark && AppPrefs.get().theme.getValue().getTheme().isDarkMode()) {
|
||||
AppPrefs.get().theme.setValue(Theme.getDefaultLightTheme());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
AppPrefs.get().theme.addListener((c, o, n) -> {
|
||||
changeTheme(n);
|
||||
});
|
||||
}
|
||||
|
||||
private static void setDefault(boolean dark) {
|
||||
if (dark) {
|
||||
AppPrefs.get().theme.setValue(Theme.getDefaultDarkTheme());
|
||||
} else {
|
||||
AppPrefs.get().theme.setValue(Theme.getDefaultLightTheme());
|
||||
}
|
||||
}
|
||||
|
||||
private static void changeTheme(Theme newTheme) {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
Application.setUserAgentStylesheet(newTheme.getTheme().getUserAgentStylesheet());
|
||||
TrackEvent.debug("Set theme " + newTheme.getId() + " for scene");
|
||||
});
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum Theme implements PrefsChoiceValue {
|
||||
PRIMER_LIGHT("light", new PrimerLight()),
|
||||
PRIMER_DARK("dark", new PrimerDark()),
|
||||
NORD_LIGHT("nordLight", new NordLight()),
|
||||
NORD_DARK("nordDark", new NordDark()),
|
||||
CUPERTINO_LIGHT("cupertinoLight", new CupertinoLight()),
|
||||
CUPERTINO_DARK("cupertinoDark", new CupertinoDark()),
|
||||
DRACULA("dracula", new Dracula());
|
||||
|
||||
static Theme getDefaultLightTheme() {
|
||||
return switch (OsType.getLocal()) {
|
||||
case OsType.Windows windows -> PRIMER_LIGHT;
|
||||
case OsType.Linux linux -> NORD_LIGHT;
|
||||
case OsType.MacOs macOs -> CUPERTINO_LIGHT;
|
||||
};
|
||||
}
|
||||
|
||||
static Theme getDefaultDarkTheme() {
|
||||
return switch (OsType.getLocal()) {
|
||||
case OsType.Windows windows -> PRIMER_DARK;
|
||||
case OsType.Linux linux -> NORD_DARK;
|
||||
case OsType.MacOs macOs -> CUPERTINO_DARK;
|
||||
};
|
||||
}
|
||||
|
||||
private final String id;
|
||||
private final atlantafx.base.theme.Theme theme;
|
||||
|
||||
@Override
|
||||
public String toTranslatedString() {
|
||||
return theme.getName();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,6 +60,7 @@ public abstract class PlatformMode extends OperationMode {
|
|||
TrackEvent.info("mode", "Platform mode initial setup");
|
||||
AppI18n.init();
|
||||
AppFont.loadFonts();
|
||||
AppTheme.init();
|
||||
AppStyle.init();
|
||||
AppImages.init();
|
||||
TrackEvent.info("mode", "Finished essential component initialization before platform");
|
||||
|
|
|
@ -11,7 +11,7 @@ import com.dlsc.preferencesfx.util.VisibilityProperty;
|
|||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.AppStyle;
|
||||
import io.xpipe.app.core.AppTheme;
|
||||
import io.xpipe.app.ext.PrefsChoiceValue;
|
||||
import io.xpipe.app.ext.PrefsHandler;
|
||||
import io.xpipe.app.ext.PrefsProvider;
|
||||
|
@ -68,8 +68,8 @@ public class AppPrefs {
|
|||
private static AppPrefs INSTANCE;
|
||||
private final SimpleListProperty<SupportedLocale> languageList =
|
||||
new SimpleListProperty<>(FXCollections.observableArrayList(Arrays.asList(SupportedLocale.values())));
|
||||
private final SimpleListProperty<AppStyle.Theme> themeList =
|
||||
new SimpleListProperty<>(FXCollections.observableArrayList(Arrays.asList(AppStyle.Theme.values())));
|
||||
private final SimpleListProperty<AppTheme.Theme> themeList =
|
||||
new SimpleListProperty<>(FXCollections.observableArrayList(Arrays.asList(AppTheme.Theme.values())));
|
||||
private final SimpleListProperty<CloseBehaviour> closeBehaviourList = new SimpleListProperty<>(
|
||||
FXCollections.observableArrayList(PrefsChoiceValue.getSupported(CloseBehaviour.class)));
|
||||
private final SimpleListProperty<ExternalEditorType> externalEditorList = new SimpleListProperty<>(
|
||||
|
@ -90,11 +90,10 @@ public class AppPrefs {
|
|||
languageList, languageInternal)
|
||||
.render(() -> new TranslatableComboBoxControl<>());
|
||||
|
||||
private final ObjectProperty<AppStyle.Theme> themeInternal =
|
||||
typed(new SimpleObjectProperty<>(AppStyle.Theme.LIGHT), AppStyle.Theme.class);
|
||||
public final ReadOnlyProperty<AppStyle.Theme> theme = themeInternal;
|
||||
private final SingleSelectionField<AppStyle.Theme> themeControl =
|
||||
Field.ofSingleSelectionType(themeList, themeInternal).render(() -> new TranslatableComboBoxControl<>());
|
||||
public final ObjectProperty<AppTheme.Theme> theme =
|
||||
typed(new SimpleObjectProperty<>(), AppTheme.Theme.class);
|
||||
private final SingleSelectionField<AppTheme.Theme> themeControl =
|
||||
Field.ofSingleSelectionType(themeList, theme).render(() -> new TranslatableComboBoxControl<>());
|
||||
private final BooleanProperty useSystemFontInternal = typed(new SimpleBooleanProperty(true), Boolean.class);
|
||||
public final ReadOnlyBooleanProperty useSystemFont = useSystemFontInternal;
|
||||
private final IntegerProperty tooltipDelayInternal = typed(new SimpleIntegerProperty(1000), Integer.class);
|
||||
|
@ -512,7 +511,7 @@ public class AppPrefs {
|
|||
Group.of(
|
||||
"uiOptions",
|
||||
Setting.of("language", languageControl, languageInternal),
|
||||
Setting.of("theme", themeControl, themeInternal),
|
||||
Setting.of("theme", themeControl, theme),
|
||||
Setting.of("useSystemFont", useSystemFontInternal),
|
||||
Setting.of("tooltipDelay", tooltipDelayInternal, tooltipDelayMin, tooltipDelayMax)),
|
||||
Group.of("windowOptions", Setting.of("saveWindowLocation", saveWindowLocationInternal))),
|
||||
|
|
|
@ -83,6 +83,8 @@ open module io.xpipe.app {
|
|||
requires java.management;
|
||||
requires jdk.management;
|
||||
requires jdk.management.agent;
|
||||
requires com.jthemedetector;
|
||||
requires versioncompare;
|
||||
|
||||
// Required by extensions
|
||||
requires commons.math3;
|
||||
|
|
BIN
gradle/gradle_scripts/atlantafx-base-1.2.1.jar
Normal file
BIN
gradle/gradle_scripts/atlantafx-base-1.2.1.jar
Normal file
Binary file not shown.
BIN
gradle/gradle_scripts/atlantafx-styles-1.2.1.jar
Normal file
BIN
gradle/gradle_scripts/atlantafx-styles-1.2.1.jar
Normal file
Binary file not shown.
BIN
gradle/gradle_scripts/jSystemThemeDetector-3.8.jar
Normal file
BIN
gradle/gradle_scripts/jSystemThemeDetector-3.8.jar
Normal file
Binary file not shown.
19
gradle/gradle_scripts/versioncompare.gradle
Normal file
19
gradle/gradle_scripts/versioncompare.gradle
Normal file
|
@ -0,0 +1,19 @@
|
|||
dependencies {
|
||||
implementation files("$buildDir/generated-modules/versioncompare-1.5.0.jar")
|
||||
}
|
||||
|
||||
addDependenciesModuleInfo {
|
||||
overwriteExistingFiles = true
|
||||
jdepsExtraArgs = ['-q']
|
||||
outputDirectory = file("$buildDir/generated-modules")
|
||||
modules {
|
||||
module {
|
||||
artifact "io.github.g00fy2:versioncompare:1.5.0"
|
||||
moduleInfoSource = '''
|
||||
module versioncompare {
|
||||
exports io.github.g00fy2.versioncompare;
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue