forked from Clones/Controlify
vmouse snapping
This commit is contained in:
@ -0,0 +1,19 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.vanilla.AbstractButtonComponentProcessor;
|
||||
import net.minecraft.client.gui.components.AbstractButton;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@Mixin(AbstractButton.class)
|
||||
public class AbstractButtonMixin implements ComponentProcessorProvider {
|
||||
@Unique private final AbstractButtonComponentProcessor controlify$processor
|
||||
= new AbstractButtonComponentProcessor((AbstractButton) (Object) this);
|
||||
|
||||
@Override
|
||||
public ComponentProcessor componentProcessor() {
|
||||
return controlify$processor;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import dev.isxander.controlify.screenop.CustomFocus;
|
||||
import net.minecraft.client.gui.components.events.AbstractContainerEventHandler;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(AbstractContainerEventHandler.class)
|
||||
public abstract class AbstractContainerEventHandlerMixin implements CustomFocus {
|
||||
@Shadow public abstract @Nullable GuiEventListener getFocused();
|
||||
|
||||
@Override
|
||||
public GuiEventListener getCustomFocus() {
|
||||
return getFocused();
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import dev.isxander.controlify.Controlify;
|
||||
import dev.isxander.controlify.InputMode;
|
||||
import net.minecraft.client.gui.components.AbstractSelectionList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
@Mixin(AbstractSelectionList.class)
|
||||
public class AbstractSelectionListMixin {
|
||||
@ModifyExpressionValue(method = "setFocused", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/InputType;isKeyboard()Z"))
|
||||
private boolean shouldEnsureEntryVisible(boolean keyboard) {
|
||||
return keyboard || Controlify.instance().currentInputMode() == InputMode.CONTROLLER;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import dev.isxander.controlify.Controlify;
|
||||
import dev.isxander.controlify.InputMode;
|
||||
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.vanilla.SliderComponentProcessor;
|
||||
import net.minecraft.client.InputType;
|
||||
import net.minecraft.client.gui.components.AbstractSliderButton;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Mixin to insert a custom {@link ComponentProcessor} into slider to support left/right movement without navigating to next component.
|
||||
*/
|
||||
@Mixin(AbstractSliderButton.class)
|
||||
public class AbstractSliderButtonMixin implements ComponentProcessorProvider {
|
||||
@Shadow private boolean canChangeValue;
|
||||
|
||||
@Unique
|
||||
private final SliderComponentProcessor controlify$processor = new SliderComponentProcessor(
|
||||
(AbstractSliderButton) (Object) this,
|
||||
() -> this.canChangeValue,
|
||||
val -> this.canChangeValue = val
|
||||
);
|
||||
|
||||
@ModifyExpressionValue(method = "setFocused", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;getLastInputType()Lnet/minecraft/client/InputType;"))
|
||||
private InputType shouldChangeValue(InputType type) {
|
||||
if (Controlify.instance().currentInputMode() == InputMode.CONTROLLER)
|
||||
return InputType.NONE; // none doesn't pass condition
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentProcessor componentProcessor() {
|
||||
return controlify$processor;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import dev.isxander.controlify.screenop.CustomFocus;
|
||||
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(ContainerObjectSelectionList.Entry.class)
|
||||
public abstract class ContainerObjectSelectionListEntryMixin implements CustomFocus {
|
||||
@Shadow public abstract @Nullable GuiEventListener getFocused();
|
||||
|
||||
@Override
|
||||
public GuiEventListener getCustomFocus() {
|
||||
return getFocused();
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(CreativeModeInventoryScreen.class)
|
||||
public interface CreativeModeInventoryScreenAccessor {
|
||||
@Accessor
|
||||
CreativeModeTab getSelectedTab();
|
||||
|
||||
@Invoker
|
||||
void invokeSelectTab(CreativeModeTab tab);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.vanilla.CreativeModeInventoryScreenProcessor;
|
||||
import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@Mixin(CreativeModeInventoryScreen.class)
|
||||
public class CreativeModeInventoryScreenMixin implements ScreenProcessorProvider {
|
||||
@Unique private final CreativeModeInventoryScreenProcessor controlify$screenProcessor
|
||||
= new CreativeModeInventoryScreenProcessor((CreativeModeInventoryScreen) (Object) this);
|
||||
|
||||
@Override
|
||||
public ScreenProcessor<?> screenProcessor() {
|
||||
return controlify$screenProcessor;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(JoinMultiplayerScreen.class)
|
||||
public interface JoinMultiplayerScreenAccessor {
|
||||
@Accessor
|
||||
Button getSelectButton();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.vanilla.JoinMultiplayerScreenProcessor;
|
||||
import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen;
|
||||
import net.minecraft.client.gui.screens.multiplayer.ServerSelectionList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@Mixin(JoinMultiplayerScreen.class)
|
||||
public class JoinMultiplayerScreenMixin implements ScreenProcessorProvider {
|
||||
@Shadow protected ServerSelectionList serverSelectionList;
|
||||
|
||||
@Unique private final JoinMultiplayerScreenProcessor controlify$processor
|
||||
= new JoinMultiplayerScreenProcessor((JoinMultiplayerScreen) (Object) this, serverSelectionList);
|
||||
|
||||
@Override
|
||||
public ScreenProcessor<?> screenProcessor() {
|
||||
return controlify$processor;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.vanilla.LanguageSelectionListComponentProcessor;
|
||||
import net.minecraft.client.gui.screens.LanguageSelectScreen;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@Mixin(LanguageSelectScreen.LanguageSelectionList.Entry.class)
|
||||
public class LanguageSelectionListEntryMixin implements ComponentProcessorProvider {
|
||||
@Shadow @Final String code;
|
||||
|
||||
@Unique private LanguageSelectionListComponentProcessor controlify$componentProcessor = null;
|
||||
|
||||
@Override
|
||||
public ComponentProcessor componentProcessor() {
|
||||
// lazily create the component processor so `code` is defined
|
||||
if (controlify$componentProcessor == null)
|
||||
controlify$componentProcessor = new LanguageSelectionListComponentProcessor(code);
|
||||
|
||||
return controlify$componentProcessor;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import net.minecraft.client.gui.screens.OptionsSubScreen;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(OptionsSubScreen.class)
|
||||
public interface OptionsSubScreenAccessor {
|
||||
@Accessor
|
||||
Screen getLastScreen();
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import net.minecraft.client.gui.ComponentPath;
|
||||
import net.minecraft.client.gui.navigation.FocusNavigationEvent;
|
||||
import net.minecraft.client.gui.navigation.ScreenDirection;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(Screen.class)
|
||||
public interface ScreenAccessor {
|
||||
@Invoker
|
||||
FocusNavigationEvent.ArrowNavigation invokeCreateArrowEvent(ScreenDirection direction);
|
||||
|
||||
@Invoker
|
||||
void invokeChangeFocus(ComponentPath path);
|
||||
|
||||
@Invoker
|
||||
void invokeClearFocus();
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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;
|
||||
|
||||
@Mixin(Screen.class)
|
||||
public class ScreenMixin implements ScreenProcessorProvider {
|
||||
@Unique
|
||||
private final ScreenProcessor<Screen> controlify$processor = new ScreenProcessor<>((Screen) (Object) this);
|
||||
|
||||
@Override
|
||||
public ScreenProcessor<Screen> screenProcessor() {
|
||||
return controlify$processor;
|
||||
}
|
||||
|
||||
@Inject(method = "rebuildWidgets", at = @At("RETURN"))
|
||||
private void onScreenInit(CallbackInfo ci) {
|
||||
screenProcessor().onWidgetRebuild();
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.worldselection.SelectWorldScreen;
|
||||
import net.minecraft.client.gui.screens.worldselection.WorldSelectionList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(SelectWorldScreen.class)
|
||||
public interface SelectWorldScreenAccessor {
|
||||
@Accessor
|
||||
Button getSelectButton();
|
||||
|
||||
@Accessor
|
||||
WorldSelectionList getList();
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.vanilla.SelectWorldScreenProcessor;
|
||||
import net.minecraft.client.gui.screens.worldselection.SelectWorldScreen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(SelectWorldScreen.class)
|
||||
public class SelectWorldScreenMixin implements ScreenProcessorProvider {
|
||||
private final SelectWorldScreenProcessor controlify$processor = new SelectWorldScreenProcessor((SelectWorldScreen) (Object) this);
|
||||
|
||||
@Override
|
||||
public ScreenProcessor<?> screenProcessor() {
|
||||
return controlify$processor;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.vanilla.ServerSelectionListEntryComponentProcessor;
|
||||
import net.minecraft.client.gui.screens.multiplayer.ServerSelectionList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@Mixin(ServerSelectionList.Entry.class)
|
||||
public class ServerSelectionListEntryMixin implements ComponentProcessorProvider {
|
||||
@Unique private final ServerSelectionListEntryComponentProcessor controlify$componentProcessor
|
||||
= new ServerSelectionListEntryComponentProcessor();
|
||||
|
||||
@Override
|
||||
public ComponentProcessor componentProcessor() {
|
||||
return ((ServerSelectionList.Entry) (Object) this) instanceof ServerSelectionList.LANHeader
|
||||
? ComponentProcessor.EMPTY
|
||||
: controlify$componentProcessor;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
|
||||
|
||||
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.vanilla.WorldListEntryComponentProcessor;
|
||||
import net.minecraft.client.gui.screens.worldselection.WorldSelectionList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(WorldSelectionList.WorldListEntry.class)
|
||||
public class WorldSelectionListEntryMixin implements ComponentProcessorProvider {
|
||||
private final WorldListEntryComponentProcessor controlify$processor = new WorldListEntryComponentProcessor();
|
||||
|
||||
@Override
|
||||
public ComponentProcessor componentProcessor() {
|
||||
return controlify$processor;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.yacl;
|
||||
|
||||
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.yacl.CyclingControllerElementComponentProcessor;
|
||||
import dev.isxander.yacl.gui.controllers.cycling.CyclingControllerElement;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@Mixin(CyclingControllerElement.class)
|
||||
public class CyclingControllerElementMixin implements ComponentProcessorProvider {
|
||||
@Unique private final CyclingControllerElementComponentProcessor controlify$processor
|
||||
= new CyclingControllerElementComponentProcessor((CyclingControllerElement) (Object) this);
|
||||
|
||||
@Override
|
||||
public ComponentProcessor componentProcessor() {
|
||||
return controlify$processor;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.yacl;
|
||||
|
||||
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.yacl.SliderControllerElementComponentProcessor;
|
||||
import dev.isxander.yacl.gui.controllers.slider.SliderControllerElement;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@Mixin(SliderControllerElement.class)
|
||||
public class SliderControllerElementMixin implements ComponentProcessorProvider {
|
||||
@Unique private final SliderControllerElementComponentProcessor controlify$processor
|
||||
= new SliderControllerElementComponentProcessor((SliderControllerElement) (Object) this);
|
||||
|
||||
@Override
|
||||
public ComponentProcessor componentProcessor() {
|
||||
return controlify$processor;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package dev.isxander.controlify.mixins.feature.screenop.yacl;
|
||||
|
||||
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
|
||||
import dev.isxander.controlify.screenop.compat.yacl.YACLScreenProcessor;
|
||||
import dev.isxander.yacl.gui.YACLScreen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@Mixin(YACLScreen.class)
|
||||
public class YACLScreenMixin implements ScreenProcessorProvider {
|
||||
@Unique private final YACLScreenProcessor controlify$processor = new YACLScreenProcessor((YACLScreen) (Object) this);
|
||||
|
||||
@Override
|
||||
public ScreenProcessor<?> screenProcessor() {
|
||||
return controlify$processor;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package dev.isxander.controlify.mixins.feature.virtualmouse.snapping;
|
||||
|
||||
import dev.isxander.controlify.virtualmouse.ISnapBehaviour;
|
||||
import dev.isxander.controlify.virtualmouse.SnapPoint;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import org.joml.Vector2i;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mixin(AbstractContainerScreen.class)
|
||||
public abstract class AbstractContainerScreenMixin<T extends AbstractContainerMenu> extends Screen implements ISnapBehaviour {
|
||||
|
||||
protected AbstractContainerScreenMixin(Component title) {
|
||||
super(title);
|
||||
}
|
||||
|
||||
@Shadow public abstract T getMenu();
|
||||
|
||||
@Shadow protected int leftPos;
|
||||
|
||||
@Shadow protected int topPos;
|
||||
|
||||
@Shadow protected int imageHeight;
|
||||
|
||||
@Override
|
||||
public Set<SnapPoint> getSnapPoints() {
|
||||
return getMenu().slots.stream()
|
||||
.map(slot -> new SnapPoint(new Vector2i(leftPos + slot.x + 8, topPos + slot.y + 8), 24))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package dev.isxander.controlify.mixins.feature.virtualmouse.snapping;
|
||||
|
||||
import dev.isxander.controlify.virtualmouse.SnapPoint;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.CreativeModeTabs;
|
||||
import org.joml.Vector2i;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Mixin(CreativeModeInventoryScreen.class)
|
||||
public abstract class CreativeModeInventoryScreenMixin extends AbstractContainerScreenMixin<CreativeModeInventoryScreen.ItemPickerMenu> {
|
||||
@Shadow protected abstract int getTabX(CreativeModeTab group);
|
||||
@Shadow private float scrollOffs;
|
||||
@Shadow private EditBox searchBox;
|
||||
@Shadow protected abstract boolean canScroll();
|
||||
|
||||
protected CreativeModeInventoryScreenMixin(Component title) {
|
||||
super(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SnapPoint> getSnapPoints() {
|
||||
Set<SnapPoint> points = super.getSnapPoints();
|
||||
for (var tab : CreativeModeTabs.tabs()) {
|
||||
boolean topRow = tab.row() == CreativeModeTab.Row.TOP;
|
||||
int x = leftPos + getTabX(tab);
|
||||
int y = topPos + (topRow ? -28 : imageHeight - 4);
|
||||
|
||||
points.add(new SnapPoint(new Vector2i(x + 13, y + 16), 38));
|
||||
}
|
||||
|
||||
if (canScroll()) {
|
||||
int scrollTop = topPos + 18;
|
||||
int scrollBottom = scrollTop + 112;
|
||||
points.add(new SnapPoint(new Vector2i(leftPos + 175 + 6, scrollTop + (int)((float)(scrollBottom - scrollTop - 17) * scrollOffs) + 7), 15));
|
||||
}
|
||||
|
||||
if (searchBox.isVisible())
|
||||
points.add(new SnapPoint(new Vector2i(searchBox.getX() + searchBox.getWidth() / 2, searchBox.getY() + searchBox.getHeight() / 2), searchBox.getHeight() + 2));
|
||||
|
||||
return points;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package dev.isxander.controlify.mixins.feature.virtualmouse.snapping;
|
||||
|
||||
import dev.isxander.controlify.virtualmouse.ISnapBehaviour;
|
||||
import dev.isxander.controlify.virtualmouse.SnapPoint;
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import org.joml.Vector2i;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mixin(Screen.class)
|
||||
public abstract class ScreenMixin implements ISnapBehaviour {
|
||||
@Shadow public abstract List<? extends GuiEventListener> children();
|
||||
|
||||
@Override
|
||||
public Set<SnapPoint> getSnapPoints() {
|
||||
return children().stream()
|
||||
.filter(child -> child instanceof AbstractWidget)
|
||||
.map(AbstractWidget.class::cast)
|
||||
.map(widget -> new SnapPoint(
|
||||
new Vector2i(widget.getX() + widget.getWidth() / 2, widget.getY() + widget.getHeight() / 2),
|
||||
Math.min(widget.getWidth(), widget.getHeight()) + 5
|
||||
))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user