Try implementing "copy to clipboard" waypoint menu action
This commit is contained in:
parent
d6f3a35191
commit
0e55d1cc37
|
@ -1,10 +1,52 @@
|
|||
package io.github.vftdan.xaeromapaddon;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import io.github.vftdan.xaeromapaddon.worldmap.WaypointRightClickOptionsRegistry;
|
||||
import io.github.vftdan.xaeromapaddon.worldmap.waypointactions.ClipboardCopyWaypointAction;
|
||||
import io.github.vftdan.xaeromapaddon.worldmap.WaypointReaderDecorator;
|
||||
import xaero.map.mods.SupportMods;
|
||||
import xaero.map.mods.SupportXaeroMinimap;
|
||||
import xaero.map.mods.gui.WaypointRenderer;
|
||||
import xaero.map.mods.gui.WaypointReader;
|
||||
import xaero.map.element.MapElementRenderer;
|
||||
|
||||
public class VftdansXaerosMapAddonClient implements ClientModInitializer {
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
// This entrypoint is suitable for setting up client-specific logic, such as rendering.
|
||||
{
|
||||
WaypointRightClickOptionsRegistry registry = WaypointRightClickOptionsRegistry.getInstance();
|
||||
registry.addFactory(new ClipboardCopyWaypointAction());
|
||||
}
|
||||
|
||||
if (FabricLoader.getInstance().isModLoaded("xaeros-world-map")) {
|
||||
injectWaypointReaderDecorator();
|
||||
} else {
|
||||
System.err.println("No xaeros-world-map");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void injectWaypointReaderDecorator() {
|
||||
try {
|
||||
SupportXaeroMinimap supportMinimap = SupportMods.xaeroMinimap;
|
||||
if (supportMinimap == null) {
|
||||
System.err.println("No xaeroMinimap mod support");
|
||||
return;
|
||||
}
|
||||
|
||||
Field waypointRendererField = SupportXaeroMinimap.class.getDeclaredField("waypointRenderer");
|
||||
waypointRendererField.setAccessible(true);
|
||||
WaypointRenderer waypointRenderer = (WaypointRenderer) waypointRendererField.get(supportMinimap);
|
||||
|
||||
Field waypointReaderField = MapElementRenderer.class.getDeclaredField("reader");
|
||||
waypointReaderField.setAccessible(true);
|
||||
waypointReaderField.set(waypointRenderer, new WaypointReaderDecorator((WaypointReader) waypointReaderField.get(waypointRenderer)));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
package io.github.vftdan.xaeromapaddon.worldmap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import xaero.map.mods.gui.WaypointReader;
|
||||
import xaero.map.mods.gui.Waypoint;
|
||||
import xaero.map.mods.gui.WaypointRenderContext;
|
||||
import xaero.map.gui.CursorBox;
|
||||
import xaero.map.gui.IRightClickableElement;
|
||||
import xaero.map.gui.dropdown.rightclick.RightClickOption;
|
||||
|
||||
public class WaypointReaderDecorator extends WaypointReader {
|
||||
private WaypointReader wrapped;
|
||||
|
||||
public WaypointReaderDecorator(WaypointReader wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseOverMenuElement(Waypoint element, int x, int y, int mouseX, int mouseY, MinecraftClient mc) {
|
||||
return wrapped.isMouseOverMenuElement(element, x, y, mouseX, mouseY, mc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHoveredOnMap(int location, Waypoint element, double mouseX, double mouseZ, double scale, double screenSizeBasedScale, double rendererDimDiv, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.isHoveredOnMap(location, element, mouseX, mouseZ, scale, screenSizeBasedScale, rendererDimDiv, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnScreen(Waypoint element, double cameraX, double cameraZ, int width, int height, double scale, double screenSizeBasedScale, double rendererDimDiv, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.isOnScreen(element, cameraX, cameraZ, width, height, scale, screenSizeBasedScale, rendererDimDiv, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CursorBox getTooltip(Waypoint element, WaypointRenderContext context, boolean overMenu) {
|
||||
return wrapped.getTooltip(element, context, overMenu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean waypointIsGood(Waypoint w, WaypointRenderContext context) {
|
||||
return wrapped.waypointIsGood(w, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden(Waypoint element, WaypointRenderContext context) {
|
||||
return wrapped.isHidden(element, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInteractable(int location, Waypoint element) {
|
||||
return wrapped.isInteractable(location, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBoxScale(int location, Waypoint element, WaypointRenderContext context) {
|
||||
return wrapped.getBoxScale(location, element, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRenderX(Waypoint element, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.getRenderX(element, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRenderZ(Waypoint element, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.getRenderZ(element, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInteractionBoxLeft(Waypoint element, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.getInteractionBoxLeft(element, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInteractionBoxRight(Waypoint element, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.getInteractionBoxRight(element, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInteractionBoxTop(Waypoint element, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.getInteractionBoxTop(element, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInteractionBoxBottom(Waypoint element, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.getInteractionBoxBottom(element, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLeftSideLength(Waypoint element, MinecraftClient mc) {
|
||||
return wrapped.getLeftSideLength(element, mc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMenuName(Waypoint element) {
|
||||
return wrapped.getMenuName(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMenuTextFillLeftPadding(Waypoint element) {
|
||||
return wrapped.getMenuTextFillLeftPadding(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFilterName(Waypoint element) {
|
||||
return wrapped.getFilterName(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<RightClickOption> getRightClickOptions(final Waypoint element, IRightClickableElement target) {
|
||||
ArrayList<RightClickOption> rightClickOptions = wrapped.getRightClickOptions(element, target);
|
||||
|
||||
for (WaypointRightClickOptionFactory factory: WaypointRightClickOptionsRegistry.getInstance()) {
|
||||
RightClickOption option = factory.create(element, target, rightClickOptions.size());
|
||||
if (option != null) {
|
||||
rightClickOptions.add(option);
|
||||
}
|
||||
}
|
||||
|
||||
return rightClickOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRightClickValid(Waypoint element) {
|
||||
return wrapped.isRightClickValid(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRightClickTitleBackgroundColor(Waypoint element) {
|
||||
return wrapped.getRightClickTitleBackgroundColor(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldScaleBoxWithOptionalScale() {
|
||||
return wrapped.shouldScaleBoxWithOptionalScale();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderBoxLeft(Waypoint element, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.getRenderBoxLeft(element, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderBoxRight(Waypoint element, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.getRenderBoxRight(element, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderBoxTop(Waypoint element, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.getRenderBoxTop(element, context, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderBoxBottom(Waypoint element, WaypointRenderContext context, float partialTicks) {
|
||||
return wrapped.getRenderBoxBottom(element, context, partialTicks);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package io.github.vftdan.xaeromapaddon.worldmap;
|
||||
|
||||
import xaero.map.mods.gui.Waypoint;
|
||||
import xaero.map.gui.IRightClickableElement;
|
||||
import xaero.map.gui.dropdown.rightclick.RightClickOption;
|
||||
|
||||
public interface WaypointRightClickOptionFactory {
|
||||
RightClickOption create(Waypoint waypoint, IRightClickableElement target, int index);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package io.github.vftdan.xaeromapaddon.worldmap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class WaypointRightClickOptionsRegistry implements Iterable<WaypointRightClickOptionFactory> {
|
||||
private static WaypointRightClickOptionsRegistry instance = null;
|
||||
|
||||
public static WaypointRightClickOptionsRegistry getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new WaypointRightClickOptionsRegistry();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ArrayList<WaypointRightClickOptionFactory> factories = new ArrayList();
|
||||
|
||||
private WaypointRightClickOptionsRegistry() {
|
||||
}
|
||||
|
||||
public void addFactory(WaypointRightClickOptionFactory factory) {
|
||||
if (factory == null) {
|
||||
return;
|
||||
}
|
||||
factories.add(factory);
|
||||
}
|
||||
|
||||
public Iterator<WaypointRightClickOptionFactory> iterator() {
|
||||
return factories.iterator();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package io.github.vftdan.xaeromapaddon.worldmap.waypointactions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.util.Clipboard;
|
||||
import xaero.common.XaeroMinimapSession;
|
||||
import xaero.common.minimap.waypoints.WaypointWorld;
|
||||
import xaero.common.minimap.waypoints.WaypointWorldRootContainer;
|
||||
import xaero.map.mods.gui.Waypoint;
|
||||
import xaero.map.mods.SupportMods;
|
||||
|
||||
public class ClipboardCopyWaypointAction implements WaypointAction {
|
||||
@Override
|
||||
public void performAction(Screen screen, Waypoint waypoint) {
|
||||
String serialized = waypointToShareableString(waypoint);
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
if (client.player != null) {
|
||||
Clipboard clipboard = new Clipboard();
|
||||
clipboard.setClipboard(client.getWindow().getHandle(), serialized);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translationKey() {
|
||||
return "gui.vftdan.xaero_right_click_waypoint.copy_to_clipboard";
|
||||
}
|
||||
|
||||
public static String waypointToShareableString(Waypoint w) {
|
||||
WaypointWorld waypointWorld = SupportMods.xaeroMinimap.getWaypointWorld();
|
||||
String dimInfo;
|
||||
if (isWaypointWorldInternal(waypointWorld)) {
|
||||
String containerKey = waypointWorld.getContainer().getKey();
|
||||
String[] containerKeyElements = containerKey.split("/");
|
||||
String internalInfo;
|
||||
if (containerKeyElements.length < 2) {
|
||||
internalInfo = "waypoints";
|
||||
} else {
|
||||
String dim = containerKeyElements[1];
|
||||
if (dim.equals("dim%0")) {
|
||||
dim = "overworld";
|
||||
} else if (dim.equals("dim%-1")) {
|
||||
dim = "the_nether";
|
||||
} else if (dim.equals("dim%1")) {
|
||||
dim = "the_end";
|
||||
}
|
||||
containerKeyElements[1] = dim;
|
||||
internalInfo = String.join("/", Arrays.copyOfRange(containerKeyElements, 1, containerKeyElements.length));
|
||||
}
|
||||
dimInfo = "Internal_" + internalInfo;
|
||||
} else {
|
||||
dimInfo = "External";
|
||||
}
|
||||
|
||||
String title = escapeWaypointComponent(w.getName());
|
||||
String icon = escapeWaypointComponent(w.getSymbol());
|
||||
String x = w.getX() + "";
|
||||
String y = w.isyIncluded() ? Integer.valueOf(w.getY()) + "" : "~";
|
||||
String z = w.getZ() + "";
|
||||
String color = w.getColor() + "";
|
||||
String isRotation = w.isRotation() + "";
|
||||
String yaw = w.getYaw() + "";
|
||||
String dimInfoEscaped = escapeWaypointComponent(dimInfo);
|
||||
return "xaero-waypoint:" + title + ":" + icon + ":" + x + ":" + y + ":" + z + ":" + color + ":" + isRotation + ":" + yaw + ":" + dimInfoEscaped;
|
||||
}
|
||||
|
||||
public static String escapeWaypointComponent(String unsafe) {
|
||||
return unsafe.replace(":", "^col^").replace("*", "^ast^").replace("-", "^min^").replace("_", "-");
|
||||
}
|
||||
|
||||
public static boolean isWaypointWorldInternal(WaypointWorld waypointWorld) {
|
||||
WaypointWorldRootContainer lhs = waypointWorld.getContainer().getRootContainer();
|
||||
WaypointWorldRootContainer rhs = XaeroMinimapSession.getCurrentSession().getWaypointsManager().getAutoWorld().getContainer().getRootContainer();
|
||||
return lhs == rhs;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package io.github.vftdan.xaeromapaddon.worldmap.waypointactions;
|
||||
|
||||
import io.github.vftdan.xaeromapaddon.worldmap.WaypointRightClickOptionFactory;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import xaero.map.gui.GuiMap;
|
||||
import xaero.map.mods.gui.Waypoint;
|
||||
import xaero.map.gui.IRightClickableElement;
|
||||
import xaero.map.gui.dropdown.rightclick.RightClickOption;
|
||||
|
||||
public interface WaypointAction extends WaypointRightClickOptionFactory {
|
||||
@Override
|
||||
default RightClickOption create(Waypoint waypoint, IRightClickableElement target, int index) {
|
||||
return new WaypointActionRightClickOption(this, waypoint, target, index);
|
||||
}
|
||||
|
||||
void performAction(Screen screen, Waypoint waypoint);
|
||||
|
||||
String translationKey();
|
||||
|
||||
public static class WaypointActionRightClickOption extends RightClickOption {
|
||||
WaypointAction action;
|
||||
Waypoint waypoint;
|
||||
|
||||
public WaypointActionRightClickOption(WaypointAction action, Waypoint waypoint, IRightClickableElement target, int index) {
|
||||
super(action.translationKey(), index, target);
|
||||
this.action = action;
|
||||
this.waypoint = waypoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAction(Screen screen) {
|
||||
action.performAction(screen, waypoint);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue