Merge remote-tracking branch 'origin/master' into fabric/master
# Conflicts: # build.gradle # gradle.properties # src/api/java/appeng/api/util/DimensionalCoord.java # src/main/java/appeng/block/paint/PaintSplotchesBakedModel.java # src/main/java/appeng/bootstrap/BlockDefinitionBuilder.java # src/main/java/appeng/client/gui/AEBaseScreen.java # src/main/java/appeng/client/gui/implementations/CraftAmountScreen.java # src/main/java/appeng/client/gui/implementations/CraftConfirmScreen.java # src/main/java/appeng/client/gui/implementations/CraftingStatusScreen.java # src/main/java/appeng/client/gui/implementations/InterfaceScreen.java # src/main/java/appeng/client/gui/implementations/InterfaceTerminalScreen.java # src/main/java/appeng/client/gui/implementations/LevelEmitterScreen.java # src/main/java/appeng/client/gui/implementations/NumberEntryWidget.java # src/main/java/appeng/client/gui/implementations/PriorityScreen.java # src/main/java/appeng/client/gui/widgets/IconButton.java # src/main/java/appeng/client/gui/widgets/NumberBox.java # src/main/java/appeng/client/gui/widgets/SettingToggleButton.java # src/main/java/appeng/client/gui/widgets/TabButton.java # src/main/java/appeng/client/render/DelegateBakedModel.java # src/main/java/appeng/client/render/DummyFluidDispatcherBakedModel.java # src/main/java/appeng/client/render/FacadeBakedItemModel.java # src/main/java/appeng/client/render/FacadeDispatcherBakedModel.java # src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyBakedModel.java # src/main/java/appeng/client/render/crafting/EncodedPatternBakedModel.java # src/main/java/appeng/client/render/model/AutoRotatingBakedModel.java # src/main/java/appeng/client/render/model/BiometricCardBakedModel.java # src/main/java/appeng/client/render/model/ColorApplicatorBakedModel.java # src/main/java/appeng/client/render/model/GlassBakedModel.java # src/main/java/appeng/client/render/model/MemoryCardBakedModel.java # src/main/java/appeng/client/render/model/SkyCompassBakedModel.java # src/main/java/appeng/client/render/tesr/ChestTileEntityRenderer.java # src/main/java/appeng/container/AEBaseContainer.java # src/main/java/appeng/container/ContainerLocator.java # src/main/java/appeng/container/guisync/SyncData.java # src/main/java/appeng/container/implementations/CellWorkbenchContainer.java # src/main/java/appeng/container/implementations/CondenserContainer.java # src/main/java/appeng/container/implementations/ContainerHelper.java # src/main/java/appeng/container/implementations/CraftConfirmContainer.java # src/main/java/appeng/container/implementations/CraftingCPUContainer.java # src/main/java/appeng/container/implementations/CraftingCPURecord.java # src/main/java/appeng/container/implementations/CraftingStatusContainer.java # src/main/java/appeng/container/implementations/IOPortContainer.java # src/main/java/appeng/container/implementations/InscriberContainer.java # src/main/java/appeng/container/implementations/InterfaceTerminalContainer.java # src/main/java/appeng/container/implementations/LevelEmitterContainer.java # src/main/java/appeng/container/implementations/MEMonitorableContainer.java # src/main/java/appeng/container/implementations/MolecularAssemblerContainer.java # src/main/java/appeng/container/implementations/PatternTermContainer.java # src/main/java/appeng/container/implementations/PriorityContainer.java # src/main/java/appeng/container/implementations/QuartzKnifeContainer.java # src/main/java/appeng/container/implementations/SpatialIOPortContainer.java # src/main/java/appeng/container/implementations/VibrationChamberContainer.java # src/main/java/appeng/container/implementations/WirelessTermContainer.java # src/main/java/appeng/core/AEConfig.java # src/main/java/appeng/core/AppEngBootstrap.java # src/main/java/appeng/core/Registration.java # src/main/java/appeng/core/api/definitions/ApiItems.java # src/main/java/appeng/core/features/registries/WorldGenRegistry.java # src/main/java/appeng/core/sync/network/NetworkHandler.java # src/main/java/appeng/core/worlddata/WorldData.java # src/main/java/appeng/datagen/providers/loot/BlockDropProvider.java # src/main/java/appeng/debug/ChunkLoaderBlockEntity.java # src/main/java/appeng/debug/ReplicatorCardItem.java # src/main/java/appeng/entity/GrowingCrystalEntity.java # src/main/java/appeng/fluids/client/gui/FluidLevelEmitterScreen.java # src/main/java/appeng/fluids/client/gui/FluidTerminalScreen.java # src/main/java/appeng/fluids/container/FluidConfigurableContainer.java # src/main/java/appeng/fluids/container/FluidInterfaceContainer.java # src/main/java/appeng/fluids/container/FluidLevelEmitterContainer.java # src/main/java/appeng/fluids/container/FluidTerminalContainer.java # src/main/java/appeng/fluids/util/AEFluidInventory.java # src/main/java/appeng/items/misc/CrystalSeedItem.java # src/main/java/appeng/items/misc/CrystalSeedRendering.java # src/main/java/appeng/items/storage/SpatialStorageCellItem.java # src/main/java/appeng/me/cluster/implementations/QuantumCluster.java # src/main/java/appeng/mixins/feature/ConfiguredFeaturesAccessor.java # src/main/java/appeng/mixins/spatial/BiomesMixin.java # src/main/java/appeng/mixins/spatial/DimensionTypeMixin.java # src/main/java/appeng/mixins/spatial/EntityMixin.java # src/main/java/appeng/mixins/spatial/SkyRenderMixin.java # src/main/java/appeng/mixins/structure/BiomeAccessor.java # src/main/java/appeng/mixins/structure/GenerationSettingsAccessor.java # src/main/java/appeng/parts/automation/FormationPlanePart.java # src/main/java/appeng/parts/automation/PlaneBakedModel.java # src/main/java/appeng/server/subcommands/SpatialStorageCommand.java # src/main/java/appeng/server/subcommands/TestMeteoritesCommand.java # src/main/java/appeng/server/subcommands/TestOreGenCommand.java # src/main/java/appeng/spatial/SpatialStorageBiome.java # src/main/java/appeng/spatial/SpatialStorageChunkGenerator.java # src/main/java/appeng/spatial/SpatialStorageDimensionIds.java # src/main/java/appeng/spatial/SpatialStorageHelper.java # src/main/java/appeng/util/Platform.java # src/main/java/appeng/worldgen/BiomeModifier.java # src/main/java/appeng/worldgen/meteorite/MeteoriteStructureStart.java # src/main/java/appeng/worldgen/meteorite/fallout/FalloutCopy.java # src/main/resources/assets/appliedenergistics2/textures/guis/states.png
This commit is contained in:
@@ -106,6 +106,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
private Stopwatch dbl_clickTimer = Stopwatch.createStarted();
|
||||
private ItemStack dbl_whichItem = ItemStack.EMPTY;
|
||||
private Slot bl_clicked;
|
||||
private boolean handlingRightClick;
|
||||
protected final List<CustomSlotWidget> guiSlots = new ArrayList<>();
|
||||
|
||||
public AEBaseScreen(T container, PlayerInventory playerInventory, Text title) {
|
||||
@@ -284,12 +285,18 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
|
||||
this.drag_click.clear();
|
||||
|
||||
// Forward right-clicks as-if they were left-clicks
|
||||
if (btn == 1) {
|
||||
for (final Object o : this.buttons) {
|
||||
final AbstractButtonWidget widget = (AbstractButtonWidget) o;
|
||||
if (widget.isMouseOver(xCoord, yCoord)) {
|
||||
return super.mouseClicked(xCoord, yCoord, 0);
|
||||
handlingRightClick = true;
|
||||
try {
|
||||
for (final Object o : this.buttons) {
|
||||
final AbstractButtonWidget widget = (AbstractButtonWidget) o;
|
||||
if (widget.isMouseOver(xCoord, yCoord)) {
|
||||
return super.mouseClicked(xCoord, yCoord, 0);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
handlingRightClick = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,16 +642,8 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
this.itemRenderer.zOffset = 0.0F;
|
||||
}
|
||||
|
||||
protected Text getGuiDisplayName(final Text in) {
|
||||
return this.hasCustomInventoryName() ? new LiteralText(this.getInventoryName()) : in;
|
||||
}
|
||||
|
||||
private boolean hasCustomInventoryName() {
|
||||
return this.handler.getCustomName() != null;
|
||||
}
|
||||
|
||||
private String getInventoryName() {
|
||||
return this.handler.getCustomName();
|
||||
protected ITextComponent getGuiDisplayName(final Text in) {
|
||||
return title.getString().isEmpty() ? in : title;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -824,6 +823,14 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true while the current event being handled is a click of the right
|
||||
* mouse button.
|
||||
*/
|
||||
public boolean isHandlingRightClick() {
|
||||
return handlingRightClick;
|
||||
}
|
||||
|
||||
public List<Rectangle> getExclusionZones() {
|
||||
return Lists.newArrayList(new Rectangle(x, y, backgroundWidth, backgroundHeight));
|
||||
}
|
||||
|
||||
@@ -46,22 +46,28 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.amountToCraft = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.CRAFT_ITEM_COUNT, value -> {
|
||||
});
|
||||
this.amountToCraft = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.CRAFT_ITEM_COUNT);
|
||||
this.amountToCraft.setValue(1);
|
||||
this.amountToCraft.setTextFieldBounds(62, 57, 50);
|
||||
this.amountToCraft.setMinValue(1);
|
||||
this.amountToCraft.setHideValidationIcon(true);
|
||||
this.amountToCraft.addButtons(children::add, this::addButton);
|
||||
|
||||
this.next = this
|
||||
.addButton(new ButtonWidget(this.x + 128, this.y + 51, 38, 20, GuiText.Next.text(), this::confirm));
|
||||
this.amountToCraft.setOnConfirm(() -> this.confirm(this.next));
|
||||
|
||||
subGui.addBackButton(this::addButton, 154, 0);
|
||||
|
||||
changeFocus(true);
|
||||
}
|
||||
|
||||
private void confirm(ButtonWidget button) {
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new CraftRequestPacket((int) this.amountToCraft.getValue(), hasShiftDown()));
|
||||
int amount = this.amountToCraft.getIntValue().orElse(0);
|
||||
if (amount <= 0) {
|
||||
return;
|
||||
}
|
||||
NetworkHandler.instance().sendToServer(new CraftRequestPacket(amount, hasShiftDown()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,23 +83,9 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
|
||||
this.bindTexture("guis/craft_amt.png");
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
|
||||
this.next.active = this.amountToCraft.getValue() > 0;
|
||||
this.next.active = this.amountToCraft.getIntValue().orElse(0) > 0;
|
||||
|
||||
this.amountToCraft.render(matrices, offsetX, offsetY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
|
||||
if (keyCode == 28) {
|
||||
this.next.onPress();
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
return "guis/craftAmt.png";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import java.util.List;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
@@ -73,10 +75,6 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
this.setScrollBar(scrollbar);
|
||||
}
|
||||
|
||||
boolean isAutoStart() {
|
||||
return this.handler.isAutoStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
@@ -87,7 +85,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
this.addButton(this.start);
|
||||
|
||||
this.selectCPU = new ButtonWidget(this.x + (219 - 180) / 2, this.y + this.backgroundHeight - 68, 180, 20,
|
||||
GuiText.CraftingCPU.withSuffix(": ").append(GuiText.Automatic.text()), btn -> selectNextCpu());
|
||||
getNextCpuButtonLabel(), btn -> selectNextCpu());
|
||||
this.selectCPU.active = false;
|
||||
this.addButton(this.selectCPU);
|
||||
|
||||
@@ -135,22 +133,22 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
}
|
||||
|
||||
private void updateCPUButtonText() {
|
||||
Text btnTextText = GuiText.CraftingCPU.withSuffix(": ").append(GuiText.Automatic.text());
|
||||
if (this.handler.getSelectedCpu() >= 0)// && status.selectedCpu < status.cpus.size() )
|
||||
{
|
||||
if (this.handler.getName() != null) {
|
||||
final String name = this.handler.getName().asTruncatedString(20);
|
||||
btnTextText = GuiText.CraftingCPU.withSuffix(": " + name);
|
||||
} else {
|
||||
btnTextText = GuiText.CraftingCPU.withSuffix(": #" + this.handler.getSelectedCpu());
|
||||
}
|
||||
this.selectCPU.setMessage(getNextCpuButtonLabel());
|
||||
}
|
||||
|
||||
private ITextComponent getNextCpuButtonLabel() {
|
||||
if (this.container.hasNoCPU()) {
|
||||
return GuiText.NoCraftingCPUs.text();
|
||||
}
|
||||
|
||||
if (this.handler.hasNoCPU()) {
|
||||
btnTextText = GuiText.NoCraftingCPUs.text();
|
||||
ITextComponent cpuName;
|
||||
if (this.container.cpuName == null) {
|
||||
cpuName = GuiText.Automatic.text();
|
||||
} else {
|
||||
cpuName = this.container.cpuName;
|
||||
}
|
||||
|
||||
this.selectCPU.setMessage(btnTextText);
|
||||
return GuiText.CraftingCPU.withSuffix(": ").append(cpuName);
|
||||
}
|
||||
|
||||
private boolean isSimulation() {
|
||||
@@ -442,7 +440,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
|
||||
if (!this.checkHotbarKeys(keyCode, scanCode)) {
|
||||
if (keyCode == 28) {
|
||||
if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) {
|
||||
this.start();
|
||||
return true;
|
||||
}
|
||||
@@ -451,7 +449,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
}
|
||||
|
||||
private void selectNextCpu() {
|
||||
final boolean backwards = getClient().mouse.wasRightButtonClicked();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
|
||||
}
|
||||
|
||||
|
||||
@@ -44,12 +44,12 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
super.init();
|
||||
|
||||
this.selectCPU = new ButtonWidget(this.x + 8, this.y + this.backgroundHeight - 25, 150, 20,
|
||||
GuiText.CraftingCPU.withSuffix(": ").append(GuiText.NoCraftingCPUs.text()), btn -> selectNextCpu());
|
||||
getNextCpuButtonLabel(), btn -> selectNextCpu());
|
||||
this.addButton(this.selectCPU);
|
||||
|
||||
subGui.addBackButton(btn -> {
|
||||
addButton(btn);
|
||||
btn.setHideEdge(13);
|
||||
btn.setHideEdge(true);
|
||||
}, 213, -4);
|
||||
}
|
||||
|
||||
@@ -60,23 +60,14 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
}
|
||||
|
||||
private void updateCPUButtonText() {
|
||||
Text btnTextText = GuiText.NoCraftingJobs.text();
|
||||
|
||||
if (this.handler.selectedCpu >= 0)// && status.selectedCpu < status.cpus.size() )
|
||||
{
|
||||
if (this.handler.myName != null) {
|
||||
final String name = this.handler.myName.asTruncatedString(20);
|
||||
btnTextText = GuiText.CPUs.withSuffix(": " + name);
|
||||
} else {
|
||||
btnTextText = GuiText.CPUs.withSuffix(": #" + this.handler.selectedCpu);
|
||||
}
|
||||
}
|
||||
this.selectCPU.setMessage(getNextCpuButtonLabel());
|
||||
}
|
||||
|
||||
private ITextComponent getNextCpuButtonLabel() {
|
||||
if (this.handler.noCPU) {
|
||||
btnTextText = GuiText.NoCraftingJobs.text();
|
||||
return GuiText.NoCraftingJobs.text();
|
||||
}
|
||||
|
||||
this.selectCPU.setMessage(btnTextText);
|
||||
return GuiText.CraftingCPU.withSuffix(": ").append(container.cpuName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,9 +75,8 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
return in; // the cup name is on the button
|
||||
}
|
||||
|
||||
// FIXME: Extract to separate class? Shared with GuiCraftConfirm
|
||||
private void selectNextCpu() {
|
||||
final boolean backwards = client.mouse.wasRightButtonClicked();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class InterfaceScreen extends UpgradeableScreen<InterfaceContainer> {
|
||||
}
|
||||
|
||||
private void selectNextInterfaceMode() {
|
||||
final boolean backwards = getClient().mouse.wasRightButtonClicked();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigButtonPacket(Settings.INTERFACE_TERMINAL, backwards));
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ import appeng.client.gui.widgets.ServerSettingToggleButton;
|
||||
import appeng.client.gui.widgets.SettingToggleButton;
|
||||
import appeng.container.implementations.LevelEmitterContainer;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
|
||||
public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer> {
|
||||
|
||||
@@ -51,15 +49,18 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT,
|
||||
this::onLevelChange);
|
||||
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT);
|
||||
this.level.setTextFieldBounds(25, 44, 75);
|
||||
this.level.addButtons(children::add, this::addButton);
|
||||
handler.setTextField(this.level);
|
||||
this.level.setValue(container.getReportingValue());
|
||||
this.level.setOnChange(this::saveReportingValue);
|
||||
this.level.setOnConfirm(this::closeScreen);
|
||||
|
||||
this.changeFocus(true);
|
||||
}
|
||||
|
||||
private void onLevelChange(long level) {
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(level)));
|
||||
private void saveReportingValue() {
|
||||
this.level.getLongValue().ifPresent(container::setReportingValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,6 +51,7 @@ import appeng.client.gui.widgets.SettingToggleButton;
|
||||
import appeng.client.gui.widgets.TabButton;
|
||||
import appeng.client.me.InternalSlotME;
|
||||
import appeng.client.me.ItemRepo;
|
||||
import appeng.client.render.StackSizeRenderer;
|
||||
import appeng.container.implementations.CraftingStatusContainer;
|
||||
import appeng.container.implementations.MEMonitorableContainer;
|
||||
import appeng.container.slot.AppEngSlot;
|
||||
@@ -237,7 +238,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
if (this.viewCell || this instanceof WirelessTermScreen) {
|
||||
this.craftingStatusBtn = this.addButton(new TabButton(this.x + 170, this.y - 4, 2 + 11 * 16,
|
||||
GuiText.CraftingStatus.text(), this.itemRenderer, btn -> showCraftingStatus()));
|
||||
this.craftingStatusBtn.setHideEdge(13);
|
||||
this.craftingStatusBtn.setHideEdge(true);
|
||||
}
|
||||
|
||||
this.isAutoFocus = SearchBoxMode.AUTOSEARCH == searchMode || SearchBoxMode.JEI_AUTOSEARCH == searchMode
|
||||
@@ -294,6 +295,16 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
|
||||
this.currentMouseX = mouseX;
|
||||
this.currentMouseY = mouseY;
|
||||
|
||||
// Show the number of active crafting jobs
|
||||
if (this.craftingStatusBtn != null && container.activeCraftingJobs != -1) {
|
||||
// The stack size renderer expects a 16x16 slot, while the button is normally
|
||||
// bigger
|
||||
int x = this.craftingStatusBtn.x + (this.craftingStatusBtn.getWidth() - 16) / 2;
|
||||
int y = this.craftingStatusBtn.y + (this.craftingStatusBtn.getHeightRealms() - 16) / 2;
|
||||
StackSizeRenderer.renderSizeLabel(font, x - this.guiLeft, y - this.guiTop,
|
||||
String.valueOf(container.activeCraftingJobs));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -358,6 +369,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
if (this.searchField != null) {
|
||||
this.searchField.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
|
||||
@@ -2,70 +2,112 @@ package appeng.client.gui.implementations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
import net.minecraft.client.gui.AbstractGui;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.NumberEntryType;
|
||||
import appeng.client.gui.widgets.ITickingWidget;
|
||||
import appeng.client.gui.widgets.NumberBox;
|
||||
import appeng.client.gui.widgets.ConfirmableTextField;
|
||||
import appeng.client.gui.widgets.ValidationIcon;
|
||||
import appeng.core.AEConfig;
|
||||
|
||||
/**
|
||||
* A utility widget that consists of a text-field to enter a number with
|
||||
* attached buttons to increment/decrement the number in fixed intervals.
|
||||
*/
|
||||
public class NumberEntryWidget implements ITickingWidget {
|
||||
public class NumberEntryWidget extends DrawableHelper {
|
||||
|
||||
private static final ITextComponent INVALID_NUMBER = new TranslationTextComponent(
|
||||
"gui.appliedenergistics2.validation.InvalidNumber");
|
||||
private static final String NUMBER_LESS_THAN_MIN_VALUE = "gui.appliedenergistics2.validation.NumberLessThanMinValue";
|
||||
private static final Text PLUS = Text.of("+");
|
||||
private static final Text MINUS = Text.of("-");
|
||||
private static final int TEXT_COLOR_ERROR = 0xFF1900;
|
||||
private static final int TEXT_COLOR_NORMAL = 0xFFFFFF;
|
||||
|
||||
private final AEBaseScreen<?> parent;
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
private final NumberBox level;
|
||||
private final ConfirmableTextField textField;
|
||||
private final NumberEntryType type;
|
||||
private List<ButtonWidget> buttons;
|
||||
private long minValue;
|
||||
private ValidationIcon validationIcon;
|
||||
|
||||
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type,
|
||||
LongConsumer changeListener) {
|
||||
// Called when the value changes
|
||||
private Runnable onChange;
|
||||
|
||||
// Called when the user presses enter while there's a valid number in the field
|
||||
private Runnable onConfirm;
|
||||
|
||||
private boolean hideValidationIcon;
|
||||
|
||||
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type) {
|
||||
this.parent = parent;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.type = type;
|
||||
|
||||
TextRenderer font = parent.getClient().textRenderer;
|
||||
int inputX = parent.getX() + x;
|
||||
int inputY = parent.getY() + y;
|
||||
this.level = new NumberBox(font, inputX, inputY, width, font.fontHeight, type.getInputType(), changeListener);
|
||||
this.level.setHasBorder(false);
|
||||
this.level.setMaxLength(16);
|
||||
this.level.setEditableColor(0xFFFFFF);
|
||||
this.level.setVisible(true);
|
||||
parent.setInitialFocus(this.level);
|
||||
FontRenderer font = parent.getMinecraft().fontRenderer;
|
||||
int inputX = parent.getGuiLeft() + x;
|
||||
int inputY = parent.getGuiTop() + y;
|
||||
this.textField = new ConfirmableTextField(font, inputX, inputY, width, font.FONT_HEIGHT,
|
||||
StringTextComponent.EMPTY);
|
||||
this.textField.setEnableBackgroundDrawing(false);
|
||||
this.textField.setMaxStringLength(16);
|
||||
this.textField.setTextColor(TEXT_COLOR_NORMAL);
|
||||
this.textField.setVisible(true);
|
||||
this.textField.setFocused2(true);
|
||||
parent.setFocusedDefault(this.textField);
|
||||
this.textField.setResponder(text -> {
|
||||
validate();
|
||||
if (onChange != null) {
|
||||
this.onChange.run();
|
||||
}
|
||||
});
|
||||
this.textField.setOnConfirm(() -> {
|
||||
// Only confirm if it's actually valid
|
||||
if (this.onConfirm != null && getLongValue().isPresent()) {
|
||||
this.onConfirm.run();
|
||||
}
|
||||
});
|
||||
validate();
|
||||
}
|
||||
|
||||
public void setOnConfirm(Runnable callback) {
|
||||
this.onConfirm = callback;
|
||||
}
|
||||
|
||||
public void setOnChange(Runnable callback) {
|
||||
this.onChange = callback;
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.level.active = active;
|
||||
this.textField.active = active;
|
||||
this.buttons.forEach(b -> b.active = active);
|
||||
}
|
||||
|
||||
public void setTextFieldBounds(int x, int y, int width) {
|
||||
this.level.x = parent.getX() + x;
|
||||
this.level.y = parent.getY() + y;
|
||||
this.level.setWidth(width);
|
||||
this.textField.x = parent.getX() + x;
|
||||
this.textField.y = parent.getY() + y;
|
||||
this.textField.setWidth(width);
|
||||
}
|
||||
|
||||
public void setMinValue(long minValue) {
|
||||
this.level.setMinValue(minValue);
|
||||
this.minValue = minValue;
|
||||
validate();
|
||||
}
|
||||
|
||||
public void addButtons(Consumer<Element> addChildren, Consumer<ButtonWidget> addButton) {
|
||||
@@ -78,54 +120,116 @@ public class NumberEntryWidget implements ITickingWidget {
|
||||
int left = parent.getX() + x;
|
||||
int top = parent.getY() + y;
|
||||
|
||||
List<ButtonWidget> buttons = new ArrayList<>(8);
|
||||
List<ButtonWidget> buttons = new ArrayList<>(9);
|
||||
|
||||
buttons.add(new ButtonWidget(left, top, 22, 20, makeLabel(PLUS, a), btn -> addQty(a)));
|
||||
buttons.add(new ButtonWidget(left + 28, top, 28, 20, makeLabel(PLUS, b), btn -> addQty(b)));
|
||||
buttons.add(new ButtonWidget(left + 62, top, 32, 20, makeLabel(PLUS, c), btn -> addQty(c)));
|
||||
buttons.add(new ButtonWidget(left + 100, top, 38, 20, makeLabel(PLUS, d), btn -> addQty(d)));
|
||||
|
||||
// Need to add these now for sensible tab-order
|
||||
buttons.forEach(addButton);
|
||||
|
||||
// Placing this here will give a sensible tab order
|
||||
addChildren.accept(this.level);
|
||||
addChildren.accept(this.textField);
|
||||
|
||||
buttons.add(new ButtonWidget(left, top + 42, 22, 20, makeLabel(MINUS, a), btn -> addQty(-a)));
|
||||
buttons.add(new ButtonWidget(left + 28, top + 42, 28, 20, makeLabel(MINUS, b), btn -> addQty(-b)));
|
||||
buttons.add(new ButtonWidget(left + 62, top + 42, 32, 20, makeLabel(MINUS, c), btn -> addQty(-c)));
|
||||
buttons.add(new ButtonWidget(left + 100, top + 42, 38, 20, makeLabel(MINUS, d), btn -> addQty(-d)));
|
||||
|
||||
// This element is not focusable
|
||||
if (!hideValidationIcon) {
|
||||
this.validationIcon = new ValidationIcon(left + 104, top + 27);
|
||||
buttons.add(this.validationIcon);
|
||||
}
|
||||
|
||||
// Add the rest to the tab order
|
||||
buttons.subList(4, buttons.size()).forEach(addButton);
|
||||
|
||||
this.buttons = buttons;
|
||||
this.buttons.forEach(addButton);
|
||||
|
||||
// we need to re-validate because the icon may now be present and needs it's
|
||||
// initial state
|
||||
this.validate();
|
||||
}
|
||||
|
||||
private void addQty(final long i) {
|
||||
long currentValue = this.level.getValue();
|
||||
long minValue = this.level.getMinValue();
|
||||
this.level.setText(String.valueOf(Math.max(minValue, currentValue + i)));
|
||||
/**
|
||||
* Returns the integer value currently in the text-field, if it is a valid
|
||||
* number and is within the allowed min/max value.
|
||||
*/
|
||||
public OptionalInt getIntValue() {
|
||||
String text = textField.getText().trim();
|
||||
try {
|
||||
int value = Integer.parseInt(text, 10);
|
||||
if (value < minValue) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
return OptionalInt.of(value);
|
||||
} catch (NumberFormatException ignored) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float partialTicks) {
|
||||
this.level.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
public void setValue(long value, boolean skipNotify) {
|
||||
this.level.setValue(value, skipNotify);
|
||||
/**
|
||||
* Returns the long value currently in the text-field, if it is a valid number
|
||||
* and is within the allowed min/max value.
|
||||
*/
|
||||
public OptionalLong getLongValue() {
|
||||
String text = textField.getText().trim();
|
||||
try {
|
||||
long value = Long.parseLong(text, 10);
|
||||
if (value < minValue) {
|
||||
return OptionalLong.empty();
|
||||
}
|
||||
return OptionalLong.of(value);
|
||||
} catch (NumberFormatException ignored) {
|
||||
return OptionalLong.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(long value) {
|
||||
setValue(value, false);
|
||||
this.textField.setText(String.valueOf(Math.max(minValue, value)));
|
||||
this.textField.setCursorPositionEnd();
|
||||
this.textField.setSelectionPos(0);
|
||||
validate();
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return level.getValue();
|
||||
private void addQty(final long i) {
|
||||
getLongValue().ifPresent(currentValue -> setValue(currentValue + i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
this.level.tick();
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float partialTicks) {
|
||||
this.textField.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
private void validate() {
|
||||
List<ITextComponent> validationErrors = new ArrayList<>();
|
||||
|
||||
String text = textField.getText().trim();
|
||||
try {
|
||||
long value = Long.parseLong(text, 10);
|
||||
if (value < minValue) {
|
||||
validationErrors.add(new TranslationTextComponent(NUMBER_LESS_THAN_MIN_VALUE, minValue));
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
validationErrors.add(INVALID_NUMBER);
|
||||
}
|
||||
|
||||
boolean valid = validationErrors.isEmpty();
|
||||
this.textField.setTextColor(valid ? TEXT_COLOR_NORMAL : TEXT_COLOR_ERROR);
|
||||
if (this.validationIcon != null) {
|
||||
this.validationIcon.setValid(valid);
|
||||
this.validationIcon.setTooltip(validationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
private Text makeLabel(Text prefix, int amount) {
|
||||
return prefix.copy().append(String.valueOf(amount));
|
||||
}
|
||||
|
||||
public void setHideValidationIcon(boolean hideValidationIcon) {
|
||||
this.hideValidationIcon = hideValidationIcon;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.text.Text;
|
||||
@@ -26,8 +28,6 @@ import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.NumberEntryType;
|
||||
import appeng.container.implementations.PriorityContainer;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
|
||||
public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
|
||||
@@ -38,24 +38,38 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, Text title) {
|
||||
super(container, playerInventory, title);
|
||||
this.subGui = new AESubScreen(this, container.getPriorityHost());
|
||||
|
||||
// This is the effective size of the background image
|
||||
xSize = 175;
|
||||
ySize = 128;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.priority = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.PRIORITY, this::onPriorityChange);
|
||||
this.priority = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.PRIORITY);
|
||||
this.priority.setTextFieldBounds(62, 57, 50);
|
||||
this.priority.setMinValue(Integer.MIN_VALUE);
|
||||
handler.setTextField(this.priority);
|
||||
this.priority.setValue(this.container.getPriorityValue());
|
||||
this.priority.addButtons(children::add, this::addButton);
|
||||
|
||||
this.subGui.addBackButton(this::addButton, 154, 0);
|
||||
|
||||
this.priority.setOnChange(this::savePriority);
|
||||
this.priority.setOnConfirm(() -> {
|
||||
savePriority();
|
||||
this.subGui.goBack();
|
||||
});
|
||||
|
||||
changeFocus(true);
|
||||
}
|
||||
|
||||
private void onPriorityChange(long priority) {
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(priority)));
|
||||
private void savePriority() {
|
||||
OptionalInt priority = this.priority.getIntValue();
|
||||
if (priority.isPresent()) {
|
||||
container.setPriority(priority.getAsInt());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,13 +80,10 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
@Override
|
||||
public void drawBG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY,
|
||||
float partialTicks) {
|
||||
this.bindTexture(getBackground());
|
||||
this.bindTexture("guis/priority.png");
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
|
||||
this.priority.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
return "guis/priority.png";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
public class ConfirmableTextField extends TextFieldWidget {
|
||||
|
||||
private Runnable onConfirm;
|
||||
|
||||
public ConfirmableTextField(FontRenderer fontRenderer, int x, int y, int width, int height, ITextComponent text) {
|
||||
super(fontRenderer, x, y, width, height, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (canWrite() && (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER)) {
|
||||
if (this.onConfirm != null) {
|
||||
this.onConfirm.run();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
public void setOnConfirm(Runnable onConfirm) {
|
||||
this.onConfirm = onConfirm;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@ package appeng.client.gui.widgets;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.audio.SoundHandler;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.texture.TextureManager;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
@@ -33,6 +34,10 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
|
||||
private boolean halfSize = false;
|
||||
|
||||
private boolean disableClickSound = false;
|
||||
|
||||
private boolean disableBackground = false;
|
||||
|
||||
public IconButton(final int x, final int y, PressAction onPress) {
|
||||
super(x, y, 16, 16, LiteralText.EMPTY, onPress);
|
||||
}
|
||||
@@ -42,6 +47,13 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
this.active = vis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playDownSound(SoundHandler soundHandler) {
|
||||
if (!disableClickSound) {
|
||||
super.playDownSound(soundHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrices, final int mouseX, final int mouseY, float partial) {
|
||||
|
||||
@@ -72,7 +84,9 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
final int uv_y = iconIndex / 16;
|
||||
final int uv_x = iconIndex - uv_y * 16;
|
||||
|
||||
drawTexture(matrices, 0, 0, 256 - 16, 256 - 16, 16, 16);
|
||||
if (!disableBackground) {
|
||||
drawTexture(matrices, 0, 0, 256 - 16, 256 - 16, 16, 16);
|
||||
}
|
||||
drawTexture(matrices, 0, 0, uv_x * 16, uv_y * 16, 16, 16);
|
||||
RenderSystem.popMatrix();
|
||||
} else {
|
||||
@@ -85,12 +99,18 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
final int uv_y = iconIndex / 16;
|
||||
final int uv_x = iconIndex - uv_y * 16;
|
||||
|
||||
drawTexture(matrices, this.x, this.y, 256 - 16, 256 - 16, 16, 16);
|
||||
if (!disableBackground) {
|
||||
drawTexture(matrices, this.x, this.y, 256 - 16, 256 - 16, 16, 16);
|
||||
}
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, uv_y * 16, 16, 16);
|
||||
}
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
if (isHovered()) {
|
||||
renderToolTip(matrixStack, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
protected abstract int getIconIndex();
|
||||
@@ -133,4 +153,20 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
this.halfSize = halfSize;
|
||||
}
|
||||
|
||||
public boolean isDisableClickSound() {
|
||||
return disableClickSound;
|
||||
}
|
||||
|
||||
public void setDisableClickSound(boolean disableClickSound) {
|
||||
this.disableClickSound = disableClickSound;
|
||||
}
|
||||
|
||||
public boolean isDisableBackground() {
|
||||
return disableBackground;
|
||||
}
|
||||
|
||||
public void setDisableBackground(boolean disableBackground) {
|
||||
this.disableBackground = disableBackground;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.LiteralText;
|
||||
|
||||
public class NumberBox extends TextFieldWidget {
|
||||
|
||||
private final LongConsumer changeListener;
|
||||
|
||||
private long lastValue;
|
||||
|
||||
private long minValue = 0;
|
||||
|
||||
private long maxValue;
|
||||
|
||||
public NumberBox(final TextRenderer fontRenderer, final int x, final int y, final int width, final int height,
|
||||
final Class<?> type, LongConsumer changeListener) {
|
||||
super(fontRenderer, x, y, width, height, new LiteralText("0"));
|
||||
this.setText("0");
|
||||
setChangedListener(this::handleTextChanged);
|
||||
this.lastValue = 0;
|
||||
this.changeListener = changeListener;
|
||||
if (type == int.class || type == Integer.class) {
|
||||
maxValue = Integer.MAX_VALUE;
|
||||
} else {
|
||||
maxValue = Long.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: This method MUST NOT BE NAMED like a method in the superclass because
|
||||
// of a ForgeGradle remapping bug
|
||||
// since it'll not remap this method's name, but it will remap the name of the
|
||||
// method reference above.
|
||||
private void handleTextChanged(String text) {
|
||||
if (text.isEmpty()) {
|
||||
setText("0"); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
|
||||
boolean canBeNegative = canBeNegative();
|
||||
if (canBeNegative && text.equals("-")) {
|
||||
// Allow this as a special case to make typing in a negative number easier
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sanitized = new StringBuilder(text);
|
||||
boolean encounteredNonZero = false;
|
||||
for (int i = 0; i < sanitized.length(); i++) {
|
||||
char ch = sanitized.charAt(i);
|
||||
if (canBeNegative && i == 0 && ch == '-') {
|
||||
continue; // Allow leading minus sign
|
||||
}
|
||||
if (ch >= '1' && ch <= '9') {
|
||||
encounteredNonZero = true;
|
||||
continue;
|
||||
}
|
||||
if (ch != '0' || !encounteredNonZero) {
|
||||
sanitized.deleteCharAt(i--);
|
||||
}
|
||||
}
|
||||
if (sanitized.length() == 0) {
|
||||
sanitized.append('0');
|
||||
}
|
||||
String sanitizedStr = sanitized.toString();
|
||||
if (!sanitizedStr.equals(text)) {
|
||||
setText(sanitizedStr); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
if (getValue() < minValue) {
|
||||
setText(String.valueOf(minValue)); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
if (getValue() > maxValue) {
|
||||
setText(String.valueOf(maxValue)); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
|
||||
reportChange();
|
||||
}
|
||||
|
||||
private void reportChange() {
|
||||
long value = getValue();
|
||||
if (value != lastValue) {
|
||||
lastValue = value;
|
||||
changeListener.accept(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(long value, boolean skipNotify) {
|
||||
// This check avoid changing the cursor position needlessly
|
||||
if (value == this.getValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (skipNotify) {
|
||||
lastValue = value;
|
||||
}
|
||||
setText(String.valueOf(value));
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
if (getText().equals("-") && canBeNegative()) {
|
||||
return lastValue; // Allow this as a special case to type in a negative number more easily
|
||||
}
|
||||
|
||||
return Long.parseLong(getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int p_keyPressed_1_, int p_keyPressed_2_, int p_keyPressed_3_) {
|
||||
if (super.keyPressed(p_keyPressed_1_, p_keyPressed_2_, p_keyPressed_3_)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Swallow key presses for numbers because they would otherwise trigger the
|
||||
// hotbar swapping unintentionally
|
||||
return isFocused() && p_keyPressed_1_ >= '0' && p_keyPressed_1_ <= '9';
|
||||
}
|
||||
|
||||
public void setMinValue(long minValue) {
|
||||
this.minValue = minValue;
|
||||
}
|
||||
|
||||
public long getMinValue() {
|
||||
return minValue;
|
||||
}
|
||||
|
||||
private boolean canBeNegative() {
|
||||
return minValue < 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
@@ -47,6 +48,7 @@ import appeng.api.config.StorageFilter;
|
||||
import appeng.api.config.TerminalStyle;
|
||||
import appeng.api.config.ViewItems;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.core.localization.ButtonToolTips;
|
||||
import appeng.util.EnumCycler;
|
||||
|
||||
@@ -89,9 +91,11 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
|
||||
registerApp(16 * 7, Settings.CONDENSER_OUTPUT, CondenserOutput.TRASH, ButtonToolTips.CondenserOutput,
|
||||
ButtonToolTips.Trash);
|
||||
registerApp(16 * 7 + 1, Settings.CONDENSER_OUTPUT, CondenserOutput.MATTER_BALLS,
|
||||
ButtonToolTips.CondenserOutput, ButtonToolTips.MatterBalls);
|
||||
ButtonToolTips.CondenserOutput,
|
||||
ButtonToolTips.MatterBalls.text(CondenserOutput.MATTER_BALLS.requiredPower));
|
||||
registerApp(16 * 7 + 2, Settings.CONDENSER_OUTPUT, CondenserOutput.SINGULARITY,
|
||||
ButtonToolTips.CondenserOutput, ButtonToolTips.Singularity);
|
||||
ButtonToolTips.CondenserOutput,
|
||||
ButtonToolTips.Singularity.text(CondenserOutput.SINGULARITY.requiredPower));
|
||||
|
||||
registerApp(16 * 9 + 1, Settings.ACCESS, AccessRestriction.READ, ButtonToolTips.IOMode,
|
||||
ButtonToolTips.Read);
|
||||
@@ -230,7 +234,13 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
|
||||
}
|
||||
|
||||
private void triggerPress() {
|
||||
boolean backwards = MinecraftClient.getInstance().mouse.wasRightButtonClicked();
|
||||
boolean backwards = false;
|
||||
// This isn't great, but we don't get any information about right-clicks
|
||||
// otherwise
|
||||
Screen currentScreen = MinecraftClient.getInstance().currentScreen;
|
||||
if (currentScreen instanceof AEBaseScreen) {
|
||||
backwards = ((AEBaseScreen<?>) currentScreen).isHandlingRightClick();
|
||||
}
|
||||
onPress.handle(this, backwards);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import net.minecraft.util.Identifier;
|
||||
public class TabButton extends ButtonWidget implements ITooltip {
|
||||
public static final Identifier TEXTURE_STATES = new Identifier("appliedenergistics2", "textures/guis/states.png");
|
||||
private final ItemRenderer itemRenderer;
|
||||
private int hideEdge = 0;
|
||||
private boolean hideEdge;
|
||||
private int myIcon = -1;
|
||||
private ItemStack myItem;
|
||||
|
||||
@@ -69,14 +69,17 @@ public class TabButton extends ButtonWidget implements ITooltip {
|
||||
|
||||
RenderSystem.enableAlphaTest();
|
||||
|
||||
int uv_x = (this.hideEdge > 0 ? 11 : 13);
|
||||
// Selects the button border from the sprite-sheet, where each type occupies a
|
||||
// 2x2 slot
|
||||
int uv_x = 8 + (this.hideEdge ? 0 : 2);
|
||||
int uv_y = 12 + (this.isFocused() ? 2 : 0);
|
||||
|
||||
final int offsetX = this.hideEdge > 0 ? 1 : 0;
|
||||
final int offsetX = this.hideEdge ? 1 : 0;
|
||||
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, 0, 25, 22);
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, uv_y * 16, 25, 22);
|
||||
|
||||
if (this.myIcon >= 0) {
|
||||
final int uv_y = this.myIcon / 16;
|
||||
uv_y = this.myIcon / 16;
|
||||
uv_x = this.myIcon - uv_y * 16;
|
||||
|
||||
drawTexture(matrices, offsetX + this.x + 3, this.y + 3, uv_x * 16, uv_y * 16, 16, 16);
|
||||
@@ -122,11 +125,11 @@ public class TabButton extends ButtonWidget implements ITooltip {
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
public int getHideEdge() {
|
||||
public boolean getHideEdge() {
|
||||
return this.hideEdge;
|
||||
}
|
||||
|
||||
public void setHideEdge(final int hideEdge) {
|
||||
public void setHideEdge(final boolean hideEdge) {
|
||||
this.hideEdge = hideEdge;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
/**
|
||||
* Displays a small icon that shows validation errors for some input control.
|
||||
*/
|
||||
public class ValidationIcon extends IconButton {
|
||||
|
||||
private final List<ITextComponent> tooltip = new ArrayList<>();
|
||||
|
||||
private boolean valid;
|
||||
|
||||
public ValidationIcon(int x, int y) {
|
||||
super(x, y, btn -> {
|
||||
});
|
||||
setDisableBackground(true);
|
||||
setDisableClickSound(true);
|
||||
setHalfSize(true);
|
||||
}
|
||||
|
||||
public void setValid(boolean valid) {
|
||||
setVisibility(!valid);
|
||||
if (valid) {
|
||||
this.tooltip.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTooltip(List<ITextComponent> lines) {
|
||||
this.tooltip.clear();
|
||||
this.tooltip.addAll(lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getIconIndex() {
|
||||
return 16 * 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changeFocus(boolean flag) {
|
||||
return false; // Cannot focus this element
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderToolTip(MatrixStack matrices, int mouseX, int mouseY) {
|
||||
if (this.tooltip.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Minecraft client = Minecraft.getInstance();
|
||||
Screen screen = client.currentScreen;
|
||||
if (screen == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
screen.func_243308_b(matrices, this.tooltip, x, y);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user