From fbde598420ae51ed7b4f22b290fa834ab2eda359 Mon Sep 17 00:00:00 2001 From: Jaffe2718 Date: Thu, 22 Aug 2024 15:44:22 +0800 Subject: [PATCH] - add file chooser for String field in 1.6.0 --- .../eu/midnightdust/core/MidnightLib.java | 10 ++ .../core/config/MidnightLibConfig.java | 2 +- .../lib/config/MidnightConfig.java | 78 ++++++++++++-- .../textures/gui/sprites/icon/explorer.png | Bin 0 -> 197 bytes fabric/src/main/resources/fabric.mod.json | 101 ++++++++++-------- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 7 files changed, 137 insertions(+), 58 deletions(-) create mode 100644 common/src/main/resources/assets/midnightlib/textures/gui/sprites/icon/explorer.png diff --git a/common/src/main/java/eu/midnightdust/core/MidnightLib.java b/common/src/main/java/eu/midnightdust/core/MidnightLib.java index b729dc1..68287e0 100755 --- a/common/src/main/java/eu/midnightdust/core/MidnightLib.java +++ b/common/src/main/java/eu/midnightdust/core/MidnightLib.java @@ -5,16 +5,26 @@ import eu.midnightdust.lib.config.AutoCommand; import eu.midnightdust.lib.config.MidnightConfig; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import javax.swing.*; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; public class MidnightLib { public static List hiddenMods = new ArrayList<>(); + public static final Logger LOGGER = LoggerFactory.getLogger("midnightlib"); @Environment(EnvType.CLIENT) public static void onInitializeClient() { + System.setProperty("java.awt.headless", "false"); + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + LOGGER.error("Error setting system look and feel", e); + } MidnightLibConfig.init("midnightlib", MidnightLibConfig.class); } @Environment(EnvType.SERVER) diff --git a/common/src/main/java/eu/midnightdust/core/config/MidnightLibConfig.java b/common/src/main/java/eu/midnightdust/core/config/MidnightLibConfig.java index 8f7af15..393c1e3 100644 --- a/common/src/main/java/eu/midnightdust/core/config/MidnightLibConfig.java +++ b/common/src/main/java/eu/midnightdust/core/config/MidnightLibConfig.java @@ -10,6 +10,6 @@ public class MidnightLibConfig extends MidnightConfig { public static ConfigButton config_screen_list = (PlatformFunctions.isModLoaded("modmenu") || Objects.equals(PlatformFunctions.getPlatformName(), "neoforge")) ? ConfigButton.MODMENU : ConfigButton.TRUE; public enum ConfigButton { - TRUE,FALSE,MODMENU + TRUE, FALSE, MODMENU } } diff --git a/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java b/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java index 1f6d0a6..b70c349 100755 --- a/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java +++ b/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java @@ -28,6 +28,8 @@ import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.Color; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -70,7 +72,7 @@ public abstract class MidnightConfig { String id; Text name; int index; - ClickableWidget colorButton; + ClickableWidget functionButton; // color picker button / explorer button Tab tab; } @@ -175,7 +177,7 @@ public abstract class MidnightConfig { if (!s.contains("#")) s = '#' + s; if (!HEXADECIMAL_ONLY.matcher(s).matches()) return false; try { - info.colorButton.setMessage(Text.literal("⬛").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB()))); + info.functionButton.setMessage(Text.literal("⬛").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB()))); } catch (Exception ignored) {} } return true; @@ -353,7 +355,9 @@ public abstract class MidnightConfig { if (e.isSlider()) widget = new MidnightSliderWidget(width - 160, 0, 150, 20, Text.of(info.tempValue), (Double.parseDouble(info.tempValue) - e.min()) / (e.max() - e.min()), info); else - widget = new TextFieldWidget(textRenderer, width - 160, 0, 150, 20, null, Text.of(info.tempValue)); + widget = new TextFieldWidget(textRenderer, + width - (160 + (e.selectionMode() > -1 ? 20 : 0)), + 0, 150, 20, null, Text.of(info.tempValue)); if (widget instanceof TextFieldWidget textField) { textField.setMaxLength(info.width); textField.setText(info.tempValue); @@ -363,15 +367,43 @@ public abstract class MidnightConfig { widget.setTooltip(getTooltip(info)); if (e.isColor()) { resetButton.setWidth(20); - ButtonWidget colorButton = ButtonWidget.builder(Text.literal("⬛"), (button -> { - })).dimensions(width - 185, 0, 20, 20).build(); + ButtonWidget colorButton = ButtonWidget.builder(Text.literal("⬛"), (button -> {})).dimensions(width - 185, 0, 20, 20).build(); try { colorButton.setMessage(Text.literal("⬛").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB()))); } catch (Exception ignored) {} - info.colorButton = colorButton; + info.functionButton = colorButton; colorButton.active = false; this.list.addButton(List.of(widget, resetButton, colorButton), name, info); - } else this.list.addButton(List.of(widget, resetButton), name, info); + } else if (e.selectionMode() > -1) { + ButtonWidget explorerButton = TextIconButtonWidget.builder( + Text.of(""), + button -> { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileSelectionMode(e.selectionMode()); + fileChooser.setDialogType(e.fileChooserType()); + fileChooser.setDialogTitle(Text.translatable(translationPrefix + info.field.getName() + ".fileChooser.title").getString()); + if ((e.selectionMode() == JFileChooser.FILES_ONLY || e.selectionMode() == JFileChooser.FILES_AND_DIRECTORIES) && + Arrays.stream(e.fileExtensions()).noneMatch("*"::equals)) { + fileChooser.setFileFilter(new FileNameExtensionFilter( + Text.translatable(translationPrefix + info.field.getName() + ".fileFilter.description").getString(), + e.fileExtensions())); + } + if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + info.value = fileChooser.getSelectedFile().getAbsolutePath(); + info.tempValue = info.value.toString(); + list.clear(); + fillList(); + } + }, + true + ).texture(Identifier.of("midnightlib","icon/explorer"), 12, 12).dimension(20, 20).build(); + explorerButton.setPosition(width - 25, 0); + resetButton.setWidth(20); + info.functionButton = explorerButton; + this.list.addButton(List.of(widget, resetButton, explorerButton), name, info); + } else { + this.list.addButton(List.of(widget, resetButton), name, info); + } } else { this.list.addButton(List.of(), name, info); } @@ -463,16 +495,44 @@ public abstract class MidnightConfig { info.tempValue = String.valueOf(info.value); } } - @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Entry { - int width() default 100; + + /** + * Entry Annotation
+ * - width: The maximum character length of the {@link String} or {@link List} field
+ * - min: The minimum value of the int, float or double field
+ * - max: The maximum value of the int, float or double field
+ * - name: The name of the field in the config screen
+ * - selectionMode: The selection mode of the file picker button for {@link String} fields, + * -1 for none, {@link JFileChooser#FILES_ONLY} for files, {@link JFileChooser#DIRECTORIES_ONLY} for directories, + * {@link JFileChooser#FILES_AND_DIRECTORIES} for both (default: -1). Remember to set the translation key + * [modid].midnightconfig.[fieldName].fileChooser.title for the file picker dialog title
+ * - fileChooserType: The type of the file picker button for {@link String} fields, + * can be {@link JFileChooser#OPEN_DIALOG} or {@link JFileChooser#SAVE_DIALOG} (default: {@link JFileChooser#OPEN_DIALOG}). + * Remember to set the translation key [modid].midnightconfig.[fieldName].fileFilter.description for the file filter description + * if "*" is not used as file extension
+ * - fileExtensions: The file extensions for the file picker button for {@link String} fields (default: {"*"}), + * only works if selectionMode is {@link JFileChooser#FILES_ONLY} or {@link JFileChooser#FILES_AND_DIRECTORIES}
+ * - isColor: If the field is a hexadecimal color code (default: false)
+ * - isSlider: If the field is a slider (default: false)
+ * - precision: The precision of the float or double field (default: 100)
+ * - category: The category of the field in the config screen (default: "default")
+ * */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface Entry { + int width() default 400; double min() default Double.MIN_NORMAL; double max() default Double.MAX_VALUE; String name() default ""; + int selectionMode() default -1; // -1 for none, 0 for file, 1 for firectory, 2 for both + int fileChooserType() default JFileChooser.OPEN_DIALOG; + String[] fileExtensions() default {"*"}; boolean isColor() default false; boolean isSlider() default false; int precision() default 100; String category() default "default"; } + @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Client {} @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Server {} @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Hidden {} diff --git a/common/src/main/resources/assets/midnightlib/textures/gui/sprites/icon/explorer.png b/common/src/main/resources/assets/midnightlib/textures/gui/sprites/icon/explorer.png new file mode 100644 index 0000000000000000000000000000000000000000..cf925b8e141574687f401251dc5aafab3fd3fa1f GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=CqbAk63)r1AkM80G2W7@`rpwLg&WfC7i}#pZ)IA12LKJ>WAf z=1.20.4" - }, + "contact": { + "homepage": "https://www.midnightdust.eu/", + "sources": "https://github.com/TeamMidnightDust/MidnightLib", + "issues": "https://github.com/TeamMidnightDust/MidnightLib/issues" + }, - "mixins": [ - "midnightlib.mixins.json" - ], + "license": "MIT", + "icon": "assets/midnightlib/icon.png", - "custom": { - "modmenu": { - "links": { - "modmenu.discord": "https://discord.midnightdust.eu/", - "modmenu.website": "https://www.midnightdust.eu/", - "midnightlib.curseforge": "https://www.curseforge.com/minecraft/mc-mods/midnightlib", - "midnightlib.modrinth": "https://modrinth.com/mod/midnightlib", - "midnightlib.wiki": "https://github.com/TeamMidnightDust/MidnightLib/wiki" - }, - "badges": [ "library" ] + "environment": "*", + "entrypoints": { + "client": [ + "eu.midnightdust.fabric.core.MidnightLibFabric" + ], + "server": [ + "eu.midnightdust.fabric.core.MidnightLibFabric" + ], + "modmenu": [ + "eu.midnightdust.lib.config.AutoModMenu" + ] + }, + "depends": { + "fabric-resource-loader-v0": "*", + "minecraft": ">=1.20.4" + }, + + "mixins": [ + "midnightlib.mixins.json" + ], + + "custom": { + "modmenu": { + "links": { + "modmenu.discord": "https://discord.midnightdust.eu/", + "modmenu.website": "https://www.midnightdust.eu/", + "midnightlib.curseforge": "https://www.curseforge.com/minecraft/mc-mods/midnightlib", + "midnightlib.modrinth": "https://modrinth.com/mod/midnightlib", + "midnightlib.wiki": "https://github.com/TeamMidnightDust/MidnightLib/wiki" + }, + "badges": [ "library" ] + } } - } } diff --git a/gradle.properties b/gradle.properties index f1222b5..3b3a7b5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ yarn_mappings=1.21+build.1 enabled_platforms=fabric,neoforge archives_base_name=midnightlib -mod_version=1.5.8 +mod_version=1.6.0 maven_group=eu.midnightdust release_type=release curseforge_id=488090 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 48c0a02..0d18421 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists