feat: implement libjf-resource-pack-entry-widgets to unify handling resource pack entry widgets
This commit is contained in:
parent
b83d5f448c
commit
80db37575f
11
libjf-resource-pack-entry-widgets-v0/build.gradle.kts
Normal file
11
libjf-resource-pack-entry-widgets-v0/build.gradle.kts
Normal file
@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
id("jfmod.module")
|
||||
}
|
||||
|
||||
base {
|
||||
archivesName = "libjf-resource-pack-entry-widgets-v0"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
modImplementation("net.fabricmc.fabric-api:fabric-api-base")
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package io.gitlab.jfronny.libjf.entrywidgets.api.v0;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.entrypoint.EntrypointContainer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.pack.ResourcePackOrganizer;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents an additional widget inserted on the right hand side of a resource pack entry (in the resource pack or data pack screen)
|
||||
*/
|
||||
public interface ResourcePackEntryWidget {
|
||||
/**
|
||||
* Lists all known widgets from right to left. Immutable.
|
||||
*/
|
||||
List<ResourcePackEntryWidget> WIDGETS = FabricLoader.getInstance()
|
||||
.getEntrypointContainers("libjf:resource_pack_entry_widget", ResourcePackEntryWidget.class)
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(entrypoint -> entrypoint.getProvider().getMetadata().getId()))
|
||||
.map(EntrypointContainer::getEntrypoint)
|
||||
.toList();
|
||||
|
||||
/**
|
||||
* Checks whether the widget should be rendered for a given pack.
|
||||
*
|
||||
* @param pack the pack to render the widget for
|
||||
* @param selectable whether the pack is selectable
|
||||
* @return whether the widget is visible
|
||||
*/
|
||||
default boolean isVisible(ResourcePackOrganizer.Pack pack, boolean selectable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of this widget.
|
||||
*
|
||||
* @param pack the pack to render the widget for
|
||||
* @return the width of the widget
|
||||
*/
|
||||
default int getWidth(ResourcePackOrganizer.Pack pack) {
|
||||
return 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height of this widget.
|
||||
*
|
||||
* @param pack the pack to render the widget for
|
||||
* @param rowHeight the height of the row containing the widget
|
||||
* @return the height of the widget
|
||||
*/
|
||||
default int getHeight(ResourcePackOrganizer.Pack pack, int rowHeight) {
|
||||
return 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Y position of this widget relative to the top of the row.
|
||||
*
|
||||
* @param pack the pack to render the widget for
|
||||
* @param rowHeight the height of the row containing the widget
|
||||
* @return the relative y position of the widget
|
||||
*/
|
||||
default int getY(ResourcePackOrganizer.Pack pack, int rowHeight) {
|
||||
return (rowHeight - getHeight(pack, rowHeight)) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the X margin of the widget.
|
||||
* Two widgets will be separated by the maximum of their X margins.
|
||||
* Also, the rightmost widget will be separated from the edge of the entry by its margin.
|
||||
*
|
||||
* @param pack the pack to render the widget for
|
||||
* @return the X margin of the widget
|
||||
*/
|
||||
default int getXMargin(ResourcePackOrganizer.Pack pack) {
|
||||
return 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the widget.
|
||||
*
|
||||
* @param pack the pack to render the widget for
|
||||
* @param context the context to draw to
|
||||
* @param x the absolute x coordinate at which to draw
|
||||
* @param y the absolute y coordinate at which to draw
|
||||
* @param hovered whether the widget is being hovered by the cursor
|
||||
* @param tickDelta the time that has passed since the last call
|
||||
*/
|
||||
void render(ResourcePackOrganizer.Pack pack, DrawContext context, int x, int y, boolean hovered, float tickDelta);
|
||||
|
||||
/**
|
||||
* Executed when a widget is clicked.
|
||||
*
|
||||
* @param pack the pack for which the widget was clicked
|
||||
*/
|
||||
void onClick(ResourcePackOrganizer.Pack pack);
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package io.gitlab.jfronny.libjf.entrywidgets.impl.mixin;
|
||||
|
||||
import io.gitlab.jfronny.libjf.entrywidgets.api.v0.ResourcePackEntryWidget;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.pack.PackListWidget;
|
||||
import net.minecraft.client.gui.screen.pack.ResourcePackOrganizer;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(PackListWidget.ResourcePackEntry.class)
|
||||
public abstract class ResourcePackEntryMixin {
|
||||
@Shadow
|
||||
protected abstract boolean isSelectable();
|
||||
@Shadow @Final
|
||||
private ResourcePackOrganizer.Pack pack;
|
||||
@Unique
|
||||
int libjf$selected = -1;
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "render(Lnet/minecraft/client/gui/DrawContext;IIIIIIIZF)V")
|
||||
private void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta, CallbackInfo info) {
|
||||
int prevMargin = 0;
|
||||
int deltaX = 2;
|
||||
boolean selectable = isSelectable();
|
||||
libjf$selected = -1;
|
||||
for (int i = 0; i < ResourcePackEntryWidget.WIDGETS.size(); i++) {
|
||||
ResourcePackEntryWidget widget = ResourcePackEntryWidget.WIDGETS.get(i);
|
||||
if (!widget.isVisible(pack, selectable)) continue;
|
||||
deltaX += Math.max(prevMargin, widget.getXMargin(pack));
|
||||
int width = widget.getWidth(pack);
|
||||
int height = widget.getHeight(pack, entryHeight);
|
||||
int entryX = x + entryWidth - deltaX - width;
|
||||
int entryY = y + widget.getY(pack, entryHeight);
|
||||
boolean widgetHovered = mouseX <= entryX + width && mouseX >= entryX && mouseY <= entryY + height && mouseY >= entryY;
|
||||
widget.render(pack, context, entryX, entryY, widgetHovered, tickDelta);
|
||||
if (widgetHovered) libjf$selected = i;
|
||||
prevMargin = widget.getXMargin(pack);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/AlwaysSelectedEntryListWidget$Entry;mouseClicked(DDI)Z"), method = "mouseClicked(DDI)Z", cancellable = true)
|
||||
public void mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> info) {
|
||||
// Inject before super call
|
||||
if (libjf$selected != -1) {
|
||||
info.setReturnValue(true);
|
||||
ResourcePackEntryWidget.WIDGETS.get(libjf$selected).onClick(pack);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "io.gitlab.jfronny.libjf.entrywidgets.impl.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"client": [
|
||||
"ResourcePackEntryMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-resource-pack-entry-widgets-v0",
|
||||
"name": "LibJF Resource Pack Entry Widgets",
|
||||
"version": "${version}",
|
||||
"authors": [
|
||||
"JFronny"
|
||||
],
|
||||
"contact": {
|
||||
"email": "projects.contact@frohnmeyer-wds.de",
|
||||
"homepage": "https://jfronny.gitlab.io",
|
||||
"issues": "https://git.frohnmeyer-wds.de/JfMods/LibJF/issues",
|
||||
"sources": "https://git.frohnmeyer-wds.de/JfMods/LibJF"
|
||||
},
|
||||
"license": "MIT",
|
||||
"environment": "*",
|
||||
"mixins": [
|
||||
{
|
||||
"config": "libjf-resource-pack-entry-widgets-v0.client.mixins.json",
|
||||
"environment": "client"
|
||||
}
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.12.0",
|
||||
"minecraft": "*"
|
||||
},
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"parent": "libjf",
|
||||
"badges": ["library"]
|
||||
}
|
||||
}
|
||||
}
|
@ -34,5 +34,7 @@ include("libjf-unsafe-v0")
|
||||
include("libjf-mainhttp-v0")
|
||||
include("libjf-web-v1")
|
||||
|
||||
include("libjf-resource-pack-entry-widgets-v0")
|
||||
|
||||
include("libjf-bom")
|
||||
include("libjf-catalog")
|
||||
|
Loading…
Reference in New Issue
Block a user