Skip to content

Commit

Permalink
chore: backport 1.3.1 to 1.21.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamalam360 committed Feb 26, 2025
2 parents f559b06 + 39ec04b commit 43dd206
Show file tree
Hide file tree
Showing 69 changed files with 1,359 additions and 856 deletions.
3 changes: 0 additions & 3 deletions .idea/scopes/Fabric_sources.xml

This file was deleted.

3 changes: 0 additions & 3 deletions .idea/scopes/Forge_sources.xml

This file was deleted.

11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
Fix dependency logic
- Ensure inherited fields are present in config GUIs (closes #13).
- When both a mod ID and config file name are specified, the config file is now saved under
`config/{mod id}/{config name}.json5` (closes #12).
- This should not be a breaking change as I am not aware of any mods registering multiple configs currently.
- Switch to fabric-api mod ID in dependencies block (closes #10).
- Enable split source sets (closes #14).
- Identify config managers by `(MOD_ID, CONFIG_NAME)` rather than by just `(CONFIG_NAME)` (closes #15).
- Allow `List<?>` config fields (closes #11).
- The reset button next to each config field now resets to the default value, rather than the value the field had when
the config screen was opened.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.7-SNAPSHOT" apply false
id "dev.architectury.loom" version "1.9-SNAPSHOT" apply false
id "com.github.breadmoirai.github-release" version "2.4.1"
id "maven-publish"
}
Expand All @@ -26,7 +26,7 @@ subprojects {

loom {
silentMojangMappingsLicense()

mixin {
useLegacyMixinAp = false
}
Expand Down
9 changes: 8 additions & 1 deletion common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ architectury {
}

loom {
accessWidenerPath = file("src/main/resources/jamlib.accesswidener")
splitEnvironmentSourceSets()

mods {
jamlib {
sourceSet sourceSets.main
sourceSet sourceSets.client
}
}
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package io.github.jamalam360.jamlib;
package io.github.jamalam360.jamlib.client;

import static io.github.jamalam360.jamlib.JamLib.JAR_RENAMING_CHECKER;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import dev.architectury.event.events.client.ClientPlayerEvent;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.ApiStatus;

@Environment(EnvType.CLIENT)
public class JamLibClient {
@ApiStatus.Internal
public static void init() {
ClientPlayerEvent.CLIENT_PLAYER_JOIN.register(JamLibClient::onPlayerJoin);
}

public static void onPlayerJoin(LocalPlayer player) {
private static void onPlayerJoin(LocalPlayer player) {
if (player != Minecraft.getInstance().player) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package io.github.jamalam360.jamlib.client.config.gui;

import dev.architectury.platform.Platform;
import io.github.jamalam360.jamlib.JamLib;
import io.github.jamalam360.jamlib.client.config.gui.entry.ConfigEntry;
import io.github.jamalam360.jamlib.client.gui.WidgetList;
import io.github.jamalam360.jamlib.config.ConfigExtensions;
import io.github.jamalam360.jamlib.config.ConfigManager;
import io.github.jamalam360.jamlib.config.HiddenInGui;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.SpriteIconButton;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.ApiStatus;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
* A screen for editing a config managed through a {@link ConfigManager}.
*/
@ApiStatus.Internal
public class ConfigScreen<T> extends Screen {

protected final ConfigManager<T> manager;
private final Screen parent;
private final List<ConfigEntry<T, ?>> entries;
private WidgetList widgetList;
private Button doneButton;

public ConfigScreen(ConfigManager<T> manager, Screen parent) {
super(createTitle(manager));
this.manager = manager;
this.parent = parent;
this.entries = new ArrayList<>();
}

@ApiStatus.Internal
public static String createTranslationKey(String modId, String configName, String path) {
if (modId.equals(configName)) {
return "config." + modId + "." + path;
} else {
return "config." + modId + "." + configName + "." + path;
}
}

protected static Component createTitle(ConfigManager<?> manager) {
String translationKey = createTranslationKey(manager.getModId(), manager.getConfigName(), "title");

if (I18n.exists(translationKey)) {
return Component.translatable(translationKey);
} else {
return Component.literal(Platform.getMod(manager.getModId()).getName());
}
}

@Override
protected void init() {
super.init();

this.addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, button -> {
this.manager.reloadFromDisk();
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
}).pos(this.width / 2 - 154, this.height - 28).size(150, 20).build());

this.doneButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, button -> {
if (this.hasChanges()) {
this.manager.save();
}

Objects.requireNonNull(this.minecraft).setScreen(this.parent);
}).pos(this.width / 2 + 4, this.height - 28).size(150, 20).build());

SpriteIconButton editManuallyButton = this.addRenderableWidget(
SpriteIconButton.builder(Component.translatable("config.jamlib.edit_manually"), button -> {
if (this.hasChanges()) {
this.manager.save();
}

Util.getPlatform().openFile(Platform.getConfigFolder().resolve(this.manager.getConfigName() + ".json5").toFile());
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
}, true).sprite(JamLib.id("writable_book"), 16, 16).size(20, 20).build()
);
editManuallyButton.setX(7);
editManuallyButton.setY(7);
this.widgetList = new WidgetList(this.minecraft, this.width, this.height - 64, 32);

if (this.entries.isEmpty()) {
for (Field field : this.manager.getConfigClass().getFields()) {
if (field.isAnnotationPresent(HiddenInGui.class)) {
continue;
}

this.entries.add(ConfigEntry.createFromField(this.manager.getModId(), this.manager.getConfigName(), field));
}
}

for (ConfigEntry<T, ?> entry : this.entries) {
this.widgetList.addWidgetGroup(entry.createWidgets(this.width));
}

this.addRenderableWidget(this.widgetList);

if (this.manager.get() instanceof ConfigExtensions<?> ext) {
List<ConfigExtensions.Link> links = ext.getLinks();

for (int i = 0; i < links.size(); i++) {
ConfigExtensions.Link link = links.get(i);
SpriteIconButton linkButton = this.addRenderableWidget(
SpriteIconButton.builder(link.getTooltip(), button -> {
try {
Util.getPlatform().openUri(link.getUrl().toURI());
} catch (Exception e) {
JamLib.LOGGER.error("Failed to open link", e);
}
}, true).sprite(link.getTexture(), 16, 16).size(20, 20).build()

);
linkButton.setX(this.width - 30 - (28 * i));
linkButton.setY(5);
}
}
}

@Override
public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
super.render(graphics, mouseX, mouseY, delta);
graphics.drawCenteredString(Minecraft.getInstance().font, this.title, this.width / 2, 12, 0xFFFFFF);
}

private boolean canExit() {
return this.entries.stream().allMatch(ConfigEntry::isValid);
}

private boolean hasChanges() {
return this.entries.stream().anyMatch(ConfigEntry::hasChanged);
}

@Override
public void tick() {
super.tick();
boolean canExit = this.canExit();

if (this.doneButton.active != canExit) {
this.doneButton.active = canExit;
}

for (int i = 0; i < this.entries.size(); i++) {
ConfigEntry<T, ?> entry = this.entries.get(i);
List<AbstractWidget> widgets = entry.getNewWidgets(this.width);
if (widgets != null) {
this.widgetList.updateWidgetGroup(i, widgets);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jamalam360.jamlib.config.gui;
package io.github.jamalam360.jamlib.client.config.gui;

import dev.architectury.platform.Platform;
import io.github.jamalam360.jamlib.config.ConfigManager;
Expand All @@ -16,17 +16,16 @@

@ApiStatus.Internal
public class SelectConfigScreen extends Screen {

private final String modId;
private final Screen parent;

public SelectConfigScreen(Screen parent, String modId) {
super(getTitleComponent(modId));
super(createTitle(modId));
this.parent = parent;
this.modId = modId;
}

private static Component getTitleComponent(String modId) {
private static Component createTitle(String modId) {
String translationKey = "config." + modId + ".title";

if (I18n.exists(translationKey)) {
Expand Down Expand Up @@ -54,7 +53,6 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
}

private static class ConfigSelectionList extends SelectionList {

public ConfigSelectionList(Minecraft minecraft, int width, int height, int y, int itemHeight) {
super(minecraft, width, height, y, itemHeight);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jamalam360.jamlib.config.gui;
package io.github.jamalam360.jamlib.client.config.gui;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
Expand All @@ -10,7 +10,6 @@

@ApiStatus.Internal
public class SelectionList extends ContainerObjectSelectionList<SelectionListEntry> {

public SelectionList(Minecraft minecraft, int width, int height, int y, int itemHeight) {
super(minecraft, width, height, y, itemHeight);
this.centerListVertically = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jamalam360.jamlib.config.gui;
package io.github.jamalam360.jamlib.client.config.gui;

import java.util.List;

Expand All @@ -17,7 +17,6 @@

@ApiStatus.Internal
public class SelectionListEntry extends ContainerObjectSelectionList.Entry<SelectionListEntry> {

private final Component title;
private final List<FormattedCharSequence> tooltip;
private final List<AbstractWidget> widgets;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.github.jamalam360.jamlib.client.config.gui.entry;

import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Button;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class BooleanConfigEntry<T> extends ConfigEntry<T, Boolean> {
@Nullable
private Button button = null;

public BooleanConfigEntry(String modId, String configName, ConfigField<T, Boolean> field) {
super(modId, configName, field);
}

@Override
public List<AbstractWidget> createElementWidgets(int left, int width) {
this.button = Button.builder(this.getComponent(Boolean.TRUE.equals(this.getFieldValue())), button -> this.setFieldValue(!(Boolean.TRUE.equals(this.getFieldValue())))).pos(left, 0).size(width, 20).build();

return List.of(this.button);
}

@Override
public void onChange() {
super.onChange();

if (this.button != null) {
this.button.setMessage(getComponent(Boolean.TRUE.equals(this.getFieldValue())));
}
}

private Component getComponent(boolean value) {
return Component.literal(value ? "Yes" : "No").withStyle(s -> s.withColor(value ? ChatFormatting.GREEN : ChatFormatting.RED));
}
}
Loading

0 comments on commit 43dd206

Please sign in to comment.