Small UI fixes and improvements (#398)

This commit is contained in:
Domi
2024-05-24 14:03:12 +02:00
committed by GitHub
parent a9b7faa98b
commit 529ea5e239
4 changed files with 204 additions and 19 deletions
@@ -0,0 +1,87 @@
package yalter.mousetweaks.api;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
/**
* This is the interface you want to implement in your GuiScreen to make it compatible with Mouse Tweaks.
* If this interface is not enough (for example, you need a custom slot click function, or if you use a custom Container
* which happens to be incompatible), check IMTModGuiContainer2Ex instead.
* If you just need to disable Mouse Tweaks or the wheel tweak, see the MouseTweaksIgnore
* or the MouseTweaksDisableWheelTweak annotations.
*/
public interface IMTModGuiContainer2 {
/**
* If you want to disable Mouse Tweaks in your GuiScreen, return true from this method.
*
* @return True if Mouse Tweaks should be disabled, false otherwise.
*/
boolean MT_isMouseTweaksDisabled();
/**
* If you want to disable the Wheel Tweak in your GuiScreen, return true from this method.
*
* @return True if the Wheel Tweak should be disabled, false otherwise.
*/
boolean MT_isWheelTweakDisabled();
/**
* Returns the Container.
*
* @return Container that is currently in use.
*/
Container MT_getContainer();
/**
* Returns the Slot that is currently selected by the player, or null if no Slot is selected.
*
* @return Slot that is located under the mouse, or null if no Slot it currently under the mouse.
*/
Slot MT_getSlotUnderMouse();
/**
* Return true if the given Slot behaves like the vanilla crafting output slots (inside the crafting table,
* or the furnace output slot, or the anvil output slot, etc.). These slots are handled differently by Mouse Tweaks.
*
* @param slot the slot to check
* @return True if slot is a crafting output slot.
*/
boolean MT_isCraftingOutput(Slot slot);
/**
* Return true if the given Slot should be ignored by Mouse Tweaks. Examples of ignored slots are the item select
* slots and the Destroy Item slot in the vanilla creative inventory.
*
* @param slot the slot to check
* @return Tru if slot should be ignored by Mouse Tweaks.
*/
boolean MT_isIgnored(Slot slot);
/**
* If your container has an RMB dragging functionality (like vanilla containers), disable it inside this method.
* This method is called every frame (render tick), which is after all mouseClicked / mouseClickMove / mouseReleased
* events are handled (although note these events are handled every game tick, which is far less frequent than every
* render tick).<br><br>
* <p>
* If true is returned from this method, Mouse Tweaks (after checking other conditions like isIgnored) will click
* the slot on which the right mouse button was initially pressed (in most cases this is the slot currently under
* mouse). This is needed because the vanilla RMB dragging functionality prevents the initial slot click.<br><br>
* <p>
* For vanilla containers this method looks like this:
* <pre>
* this.ignoreMouseUp = true;
*
* if (this.dragSplitting) {
* if (this.dragSplittingButton == 1) {
* this.dragSplitting = false;
* return true;
* }
* }
*
* return false;
* </pre>
*
* @return True if Mouse Tweaks should click the slot on which the RMB was pressed.
*/
boolean MT_disableRMBDraggingFunctionality();
}
@@ -1,14 +0,0 @@
package yalter.mousetweaks.api;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Put this on your GuiScreen to disable Mouse Tweaks.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MouseTweaksIgnore {
}
+112 -5
View File
@@ -72,7 +72,7 @@ import net.minecraftforge.fml.common.Optional;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import yalter.mousetweaks.api.MouseTweaksIgnore; import yalter.mousetweaks.api.IMTModGuiContainer2;
import java.awt.*; import java.awt.*;
import java.io.IOException; import java.io.IOException;
@@ -85,9 +85,8 @@ import java.util.concurrent.TimeUnit;
import static appeng.integration.modules.jei.JEIPlugin.aeGuiHandler; import static appeng.integration.modules.jei.JEIPlugin.aeGuiHandler;
import static appeng.integration.modules.jei.JEIPlugin.runtime; import static appeng.integration.modules.jei.JEIPlugin.runtime;
@Optional.Interface(iface = "yalter.mousetweaks.api.IMTModGuiContainer2", modid = "mousetweaks")
@MouseTweaksIgnore public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContainer2 {
public abstract class AEBaseGui extends GuiContainer {
private final List<InternalSlotME> meSlots = new ArrayList<>(); private final List<InternalSlotME> meSlots = new ArrayList<>();
// drag y // drag y
private final Set<Slot> drag_click = new HashSet<>(); private final Set<Slot> drag_click = new HashSet<>();
@@ -950,10 +949,42 @@ public abstract class AEBaseGui extends GuiContainer {
this.zLevel = 0.0F; this.zLevel = 0.0F;
this.itemRender.zLevel = 0.0F; this.itemRender.zLevel = 0.0F;
boolean wasDragSplitting = this.dragSplitting;
this.dragSplitting = false; // to prevent the vanilla slot renderer from rendering the stack count during drag splitting, we're re-enabling it later
// Annoying but easier than trying to splice into render item // Annoying but easier than trying to splice into render item
super.drawSlot(s); super.drawSlot(s);
this.stackSizeRenderer.renderStackSize(this.fontRenderer, AEItemStack.fromItemStack(appEngSlot.getDisplayStack()), s.xPos, s.yPos); ItemStack stackInSlot = ((AppEngSlot)s).getDisplayStack();
ItemStack stackUnderCursor = this.mc.player.inventory.getItemStack();
if (wasDragSplitting
&& this.dragSplittingSlots.contains(s)
&& this.dragSplittingSlots.size() > 1
&& !stackUnderCursor.isEmpty()) {
if (Container.canAddItemToSlot(s, stackUnderCursor, true) && this.inventorySlots.canDragIntoSlot(s))
{
drawRect(s.xPos, s.yPos, s.xPos + 16, s.yPos + 16, -2130706433);
stackInSlot = stackUnderCursor.copy();
Container.computeStackSize(this.dragSplittingSlots, this.dragSplittingLimit, stackInSlot, s.getStack().isEmpty() ? 0 : s.getStack().getCount());
int k = Math.min(stackInSlot.getMaxStackSize(), s.getItemStackLimit(stackInSlot));
if (stackInSlot.getCount() > k)
{
stackInSlot.setCount(k);
}
}
else
{
this.dragSplittingSlots.remove(s);
this.updateDragSplitting();
}
}
this.dragSplitting = wasDragSplitting;
this.stackSizeRenderer.renderStackSize(this.fontRenderer, AEItemStack.fromItemStack(stackInSlot), s.xPos, s.yPos);
return; return;
} else { } else {
super.drawSlot(s); super.drawSlot(s);
@@ -988,4 +1019,80 @@ public abstract class AEBaseGui extends GuiContainer {
protected List<InternalSlotME> getMeSlots() { protected List<InternalSlotME> getMeSlots() {
return this.meSlots; return this.meSlots;
} }
// TODO: remove this when refactoring slot rendering
private void updateDragSplitting()
{
ItemStack itemstack = this.mc.player.inventory.getItemStack();
if (!itemstack.isEmpty() && this.dragSplitting)
{
if (this.dragSplittingLimit == 2)
{
this.dragSplittingRemnant = itemstack.getMaxStackSize();
}
else
{
this.dragSplittingRemnant = itemstack.getCount();
for (Slot slot : this.dragSplittingSlots)
{
ItemStack itemstack1 = itemstack.copy();
ItemStack itemstack2 = slot.getStack();
int i = itemstack2.isEmpty() ? 0 : itemstack2.getCount();
Container.computeStackSize(this.dragSplittingSlots, this.dragSplittingLimit, itemstack1, i);
int j = Math.min(itemstack1.getMaxStackSize(), slot.getItemStackLimit(itemstack1));
if (itemstack1.getCount() > j)
{
itemstack1.setCount(j);
}
this.dragSplittingRemnant -= itemstack1.getCount() - i;
}
}
}
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isMouseTweaksDisabled() {
return true;
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isWheelTweakDisabled() {
return true;
}
@Override
@Optional.Method(modid = "mousetweaks")
public Container MT_getContainer() {
return this.inventorySlots;
}
@Override
@Optional.Method(modid = "mousetweaks")
public Slot MT_getSlotUnderMouse() {
return getSlotUnderMouse();
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isCraftingOutput(Slot slot) {
return slot instanceof SlotOutput || slot instanceof AppEngCraftingSlot;
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isIgnored(Slot slot) {
return true;
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_disableRMBDraggingFunctionality() {
return true;
}
} }
@@ -467,6 +467,7 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
} }
final boolean mouseInGui = this.isPointInRegion(0, 0, this.xSize, this.ySize, this.currentMouseX, this.currentMouseY); final boolean mouseInGui = this.isPointInRegion(0, 0, this.xSize, this.ySize, this.currentMouseX, this.currentMouseY);
final boolean wasSearchFieldFocused = this.searchField.isFocused();
if (this.isAutoFocus && !this.searchField.isFocused() && mouseInGui) { if (this.isAutoFocus && !this.searchField.isFocused() && mouseInGui) {
this.searchField.setFocused(true); this.searchField.setFocused(true);
@@ -478,6 +479,10 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
// tell forge the key event is handled and should not be sent out // tell forge the key event is handled and should not be sent out
this.keyHandled = mouseInGui; this.keyHandled = mouseInGui;
} else { } else {
if (!wasSearchFieldFocused) {
// prevent unhandled keys (like shift) from focusing the search field
searchField.setFocused(false);
}
super.keyTyped(character, key); super.keyTyped(character, key);
} }
} }