mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-26 23:19:02 +01:00
Keeping notes
- Added the Clipboard
This commit is contained in:
parent
36cd43997d
commit
9dd5cde745
24 changed files with 1068 additions and 3 deletions
|
@ -566,8 +566,8 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
|
|||
5616dda664dd106d576848124fc0fc1de18d0fd3 assets/create/blockstates/yellow_valve_handle.json
|
||||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
|
||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||
f1bedeb51c35e70a2247178634e61ea637a6622e assets/create/lang/en_ud.json
|
||||
59fd557ef593efa3c7b783195ec5dc789eae1834 assets/create/lang/en_us.json
|
||||
0f4e5a2fc58580df5b156fdac438ddeb6b57e386 assets/create/lang/en_ud.json
|
||||
85d790bedbdc65bb6e6377edcc63e7b00455e879 assets/create/lang/en_us.json
|
||||
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
||||
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
||||
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json
|
||||
|
@ -1663,6 +1663,10 @@ f7aca6aff65e1de269a99cf2a280d9841b7a0076 assets/create/models/item/brass_sheet.j
|
|||
87637b39c3a5a386457d52b37eb65f1c4bcabaf0 assets/create/models/item/chocolate_glazed_berries.json
|
||||
fe67c3f380d17735a9436a4579a8be1a02b8e4a0 assets/create/models/item/chute.json
|
||||
6680a68526576ded5dac2aa3bc9fb9de3e744146 assets/create/models/item/cinder_flour.json
|
||||
0f79260d962011817a41af8c46996f426669b089 assets/create/models/item/clipboard.json
|
||||
1bd8ad56fe261f3ff2f7bb2ac12f691a76ae5c94 assets/create/models/item/clipboard_0.json
|
||||
7a4d58451e051796e21138faf3428f3d3c14ef85 assets/create/models/item/clipboard_1.json
|
||||
376e88de90f33fd32f3f2ffe0062ae5b3bdc1370 assets/create/models/item/clipboard_2.json
|
||||
c1da21be9f1af4f7a2ef4ec9cd92195d65ada316 assets/create/models/item/clockwork_bearing.json
|
||||
0a2a0f0aafeab0088172f77afd40c1fa2cc1f2b8 assets/create/models/item/clutch.json
|
||||
dcb09deae110077bcddf090996b51cc66e9a7de3 assets/create/models/item/cogwheel.json
|
||||
|
|
|
@ -595,6 +595,7 @@
|
|||
"item.create.chocolate_glazed_berries": "s\u01DD\u0131\u0279\u0279\u01DD\u15FA p\u01DDz\u0250\u05DF\u2141 \u01DD\u0287\u0250\u05DFo\u0254o\u0265\u0186",
|
||||
"item.create.chromatic_compound": "punod\u026Fo\u0186 \u0254\u0131\u0287\u0250\u026Fo\u0279\u0265\u0186",
|
||||
"item.create.cinder_flour": "\u0279no\u05DF\u2132 \u0279\u01DDpu\u0131\u0186",
|
||||
"item.create.clipboard": "p\u0279\u0250oqd\u0131\u05DF\u0186",
|
||||
"item.create.copper_backtank": "\u029Eu\u0250\u0287\u029E\u0254\u0250\u15FA \u0279\u01DDddo\u0186",
|
||||
"item.create.copper_backtank_placeable": "\u01DD\u05DFq\u0250\u01DD\u0254\u0250\u05DF\u0500 \u029Eu\u0250\u0287\u029E\u0254\u0250\u15FA \u0279\u01DDddo\u0186",
|
||||
"item.create.copper_diving_boots": "s\u0287oo\u15FA bu\u0131\u028C\u0131\u15E1 \u0279\u01DDddo\u0186",
|
||||
|
|
|
@ -602,6 +602,7 @@
|
|||
"item.create.chocolate_glazed_berries": "Chocolate Glazed Berries",
|
||||
"item.create.chromatic_compound": "Chromatic Compound",
|
||||
"item.create.cinder_flour": "Cinder Flour",
|
||||
"item.create.clipboard": "Clipboard",
|
||||
"item.create.copper_backtank": "Copper Backtank",
|
||||
"item.create.copper_backtank_placeable": "Copper Backtank Placeable",
|
||||
"item.create.copper_diving_boots": "Copper Diving Boots",
|
||||
|
@ -1130,6 +1131,7 @@
|
|||
"create.gui.sequenced_gearshift.speed.forward_fast": "Double speed, Forwards",
|
||||
"create.gui.sequenced_gearshift.speed.back": "Input speed, Reversed",
|
||||
"create.gui.sequenced_gearshift.speed.back_fast": "Double speed, Reversed",
|
||||
"create.gui.clipboard.erase_checked": "Erase checked items",
|
||||
|
||||
"create.schematicAndQuill.dimensions": "Schematic Size: %1$sx%2$sx%3$s",
|
||||
"create.schematicAndQuill.firstPos": "First position set.",
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "create:item/clipboard"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"predicate": {
|
||||
"create:clipboard_type": 0.0
|
||||
},
|
||||
"model": "create:item/clipboard_0"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"create:clipboard_type": 1.0
|
||||
},
|
||||
"model": "create:item/clipboard_1"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"create:clipboard_type": 2.0
|
||||
},
|
||||
"model": "create:item/clipboard_2"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "create:item/empty_clipboard"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "create:item/clipboard"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "create:item/clipboard_and_quill"
|
||||
}
|
||||
}
|
|
@ -39,6 +39,8 @@ import com.simibubi.create.content.curiosities.armor.BacktankItem;
|
|||
import com.simibubi.create.content.curiosities.armor.BacktankItem.BacktankBlockItem;
|
||||
import com.simibubi.create.content.curiosities.armor.DivingBootsItem;
|
||||
import com.simibubi.create.content.curiosities.armor.DivingHelmetItem;
|
||||
import com.simibubi.create.content.curiosities.clipboard.ClipboardItem;
|
||||
import com.simibubi.create.content.curiosities.clipboard.ClipboardOverrides;
|
||||
import com.simibubi.create.content.curiosities.symmetry.SymmetryWandItem;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintItem;
|
||||
import com.simibubi.create.content.curiosities.tools.ExtendoGripItem;
|
||||
|
@ -72,7 +74,10 @@ public class AllItems {
|
|||
REGISTRATE.creativeModeTab(() -> AllCreativeModeTabs.BASE_CREATIVE_TAB);
|
||||
}
|
||||
|
||||
// Materials
|
||||
public static final ItemEntry<ClipboardItem> CLIPBOARD = REGISTRATE.item("clipboard", ClipboardItem::new)
|
||||
.onRegister(ClipboardItem::registerModelOverrides)
|
||||
.model((c, p) -> ClipboardOverrides.addOverrideModels(c, p))
|
||||
.register();
|
||||
|
||||
public static final ItemEntry<Item> WHEAT_FLOUR =
|
||||
taggedIngredient("wheat_flour", forgeItemTag("flour/wheat"), forgeItemTag("flour")),
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package com.simibubi.create.content.curiosities.clipboard;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.network.NetworkEvent.Context;
|
||||
|
||||
public class ClipboardEditPacket extends SimplePacketBase {
|
||||
|
||||
private int hotbarSlot;
|
||||
private CompoundTag data;
|
||||
|
||||
public ClipboardEditPacket(int hotbarSlot, CompoundTag data) {
|
||||
this.hotbarSlot = hotbarSlot;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public ClipboardEditPacket(FriendlyByteBuf buffer) {
|
||||
hotbarSlot = buffer.readVarInt();
|
||||
data = buffer.readNbt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
buffer.writeVarInt(hotbarSlot);
|
||||
buffer.writeNbt(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Context context) {
|
||||
ServerPlayer sender = context.getSender();
|
||||
ItemStack itemStack = sender.getInventory()
|
||||
.getItem(hotbarSlot);
|
||||
if (!AllItems.CLIPBOARD.isIn(itemStack))
|
||||
return true;
|
||||
itemStack.setTag(data.isEmpty() ? null : data);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.simibubi.create.content.curiosities.clipboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class ClipboardEntry {
|
||||
|
||||
boolean checked;
|
||||
MutableComponent text;
|
||||
|
||||
public ClipboardEntry(boolean checked, MutableComponent text) {
|
||||
this.checked = checked;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public static List<List<ClipboardEntry>> readAll(ItemStack clipboardItem) {
|
||||
CompoundTag tag = clipboardItem.getTag();
|
||||
if (tag == null)
|
||||
return new ArrayList<>();
|
||||
return NBTHelper.readCompoundList(tag.getList("Pages", Tag.TAG_COMPOUND), pageTag -> NBTHelper
|
||||
.readCompoundList(pageTag.getList("Entries", Tag.TAG_COMPOUND), ClipboardEntry::readNBT));
|
||||
}
|
||||
|
||||
public static void saveAll(List<List<ClipboardEntry>> entries, ItemStack clipboardItem) {
|
||||
CompoundTag tag = clipboardItem.getOrCreateTag();
|
||||
tag.put("Pages", NBTHelper.writeCompoundList(entries, list -> {
|
||||
CompoundTag pageTag = new CompoundTag();
|
||||
pageTag.put("Entries", NBTHelper.writeCompoundList(list, ClipboardEntry::writeNBT));
|
||||
return pageTag;
|
||||
}));
|
||||
}
|
||||
|
||||
public CompoundTag writeNBT() {
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
nbt.putBoolean("Checked", checked);
|
||||
nbt.putString("Text", Component.Serializer.toJson(text));
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public static ClipboardEntry readNBT(CompoundTag tag) {
|
||||
return new ClipboardEntry(tag.getBoolean("Checked"), Component.Serializer.fromJson(tag.getString("Text")));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.simibubi.create.content.curiosities.clipboard;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class ClipboardItem extends Item {
|
||||
|
||||
public ClipboardItem(Properties pProperties) {
|
||||
super(pProperties);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public InteractionResult useOn(UseOnContext context) {
|
||||
if (context.getPlayer() == null)
|
||||
return InteractionResult.PASS;
|
||||
return use(context.getLevel(), context.getPlayer(), context.getHand()).getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand hand) {
|
||||
ItemStack heldItem = player.getItemInHand(hand);
|
||||
if (hand == InteractionHand.OFF_HAND)
|
||||
return InteractionResultHolder.pass(heldItem);
|
||||
|
||||
player.getCooldowns()
|
||||
.addCooldown(heldItem.getItem(), 10);
|
||||
if (world.isClientSide)
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> openScreen(player, heldItem));
|
||||
CompoundTag tag = heldItem.getOrCreateTag();
|
||||
tag.putInt("Type", ClipboardOverrides.ClipboardType.EDITING.ordinal());
|
||||
heldItem.setTag(tag);
|
||||
|
||||
return InteractionResultHolder.success(heldItem);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private void openScreen(Player player, ItemStack stack) {
|
||||
if (Minecraft.getInstance().player == player)
|
||||
ScreenOpener.open(new ClipboardScreen(player.getInventory().selected, stack));
|
||||
}
|
||||
|
||||
public void registerModelOverrides() {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClipboardOverrides.registerModelOverridesClient(this));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package com.simibubi.create.content.curiosities.clipboard;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.tterrag.registrate.providers.DataGenContext;
|
||||
import com.tterrag.registrate.providers.RegistrateItemModelProvider;
|
||||
|
||||
import net.minecraft.client.renderer.item.ItemProperties;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.client.model.generators.ItemModelBuilder;
|
||||
import net.minecraftforge.client.model.generators.ModelFile.UncheckedModelFile;
|
||||
|
||||
public class ClipboardOverrides {
|
||||
|
||||
public enum ClipboardType {
|
||||
EMPTY("empty_clipboard"), WRITTEN("clipboard"), EDITING("clipboard_and_quill");
|
||||
|
||||
public String file;
|
||||
public static ResourceLocation ID = Create.asResource("clipboard_type");
|
||||
|
||||
private ClipboardType(String file) {
|
||||
this.file = file;
|
||||
}
|
||||
}
|
||||
|
||||
public static void switchTo(ClipboardType type, ItemStack clipboardItem) {
|
||||
CompoundTag tag = clipboardItem.getOrCreateTag();
|
||||
tag.putInt("Type", type.ordinal());
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static void registerModelOverridesClient(ClipboardItem item) {
|
||||
ItemProperties.register(item, ClipboardType.ID, (pStack, pLevel, pEntity, pSeed) -> {
|
||||
CompoundTag tag = pStack.getTag();
|
||||
return tag == null ? 0 : tag.getInt("Type");
|
||||
});
|
||||
}
|
||||
|
||||
public static ItemModelBuilder addOverrideModels(DataGenContext<Item, ClipboardItem> c,
|
||||
RegistrateItemModelProvider p) {
|
||||
ItemModelBuilder builder = p.generated(() -> c.get());
|
||||
for (int i = 0; i < ClipboardType.values().length; i++) {
|
||||
builder.override()
|
||||
.predicate(ClipboardType.ID, i)
|
||||
.model(p.getBuilder(c.getName() + "_" + i)
|
||||
.parent(new UncheckedModelFile("item/generated"))
|
||||
.texture("layer0", Create.asResource("item/" + ClipboardType.values()[i].file)))
|
||||
.end();
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,775 @@
|
|||
package com.simibubi.create.content.curiosities.clipboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.simibubi.create.content.curiosities.clipboard.ClipboardOverrides.ClipboardType;
|
||||
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
|
||||
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.widget.IconButton;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.StringSplitter;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
import net.minecraft.client.gui.font.TextFieldHelper;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.PageButton;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.Rect2i;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public class ClipboardScreen extends AbstractSimiScreen {
|
||||
|
||||
private ItemStack item;
|
||||
|
||||
List<List<ClipboardEntry>> pages;
|
||||
List<ClipboardEntry> currentEntries;
|
||||
int editingIndex;
|
||||
int frameTick;
|
||||
PageButton forward;
|
||||
PageButton backward;
|
||||
int currentPage;
|
||||
long lastClickTime;
|
||||
int lastIndex = -1;
|
||||
|
||||
int hoveredEntry;
|
||||
boolean hoveredCheck;
|
||||
|
||||
DisplayCache displayCache = DisplayCache.EMPTY;
|
||||
TextFieldHelper editContext;
|
||||
|
||||
IconButton closeBtn;
|
||||
IconButton clearBtn;
|
||||
|
||||
private int targetSlot;
|
||||
|
||||
public ClipboardScreen(int targetSlot, ItemStack item) {
|
||||
this.targetSlot = targetSlot;
|
||||
this.item = item;
|
||||
pages = ClipboardEntry.readAll(item);
|
||||
if (pages.isEmpty())
|
||||
pages.add(new ArrayList<>());
|
||||
currentPage = item.getTag() == null ? 0
|
||||
: item.getTag()
|
||||
.getInt("PreviouslyOpenedPage");
|
||||
currentPage = Mth.clamp(currentPage, 0, pages.size() - 1);
|
||||
currentEntries = pages.get(currentPage);
|
||||
boolean startEmpty = currentEntries.isEmpty();
|
||||
if (startEmpty)
|
||||
currentEntries.add(new ClipboardEntry(false, Components.empty()));
|
||||
editingIndex = 0;
|
||||
editContext = new TextFieldHelper(this::getCurrentEntryText, this::setCurrentEntryText, this::getClipboard,
|
||||
this::setClipboard, this::validateTextForEntry);
|
||||
editingIndex = startEmpty ? 0 : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
setWindowSize(256, 256);
|
||||
super.init();
|
||||
minecraft.keyboardHandler.setSendRepeatsToGui(true);
|
||||
clearDisplayCache();
|
||||
|
||||
int x = guiLeft;
|
||||
int y = guiTop - 8;
|
||||
|
||||
clearWidgets();
|
||||
clearBtn = new IconButton(x + 234, y + 153, AllIcons.I_CLEAR_CHECKED).withCallback(() -> {
|
||||
editingIndex = -1;
|
||||
currentEntries.removeIf(ce -> ce.checked);
|
||||
if (currentEntries.isEmpty())
|
||||
currentEntries.add(new ClipboardEntry(false, Components.empty()));
|
||||
});
|
||||
clearBtn.setToolTip(Lang.translateDirect("gui.clipboard.erase_checked"));
|
||||
closeBtn = new IconButton(x + 234, y + 175, AllIcons.I_PRIORITY_VERY_LOW)
|
||||
.withCallback(() -> minecraft.setScreen(null));
|
||||
closeBtn.setToolTip(Lang.translateDirect("station.close"));
|
||||
addRenderableWidget(closeBtn);
|
||||
addRenderableWidget(clearBtn);
|
||||
|
||||
forward = new PageButton(x + 176, y + 229, true, $ -> changePage(true), true);
|
||||
backward = new PageButton(x + 53, y + 229, false, $ -> changePage(false), true);
|
||||
addRenderableWidget(forward);
|
||||
addRenderableWidget(backward);
|
||||
|
||||
forward.visible = currentPage < 50;
|
||||
backward.visible = currentPage > 0;
|
||||
}
|
||||
|
||||
private int getNumPages() {
|
||||
return pages.size();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
frameTick++;
|
||||
|
||||
int mx = (int) (this.minecraft.mouseHandler.xpos() * (double) this.minecraft.getWindow()
|
||||
.getGuiScaledWidth() / (double) this.minecraft.getWindow()
|
||||
.getScreenWidth());
|
||||
int my = (int) (this.minecraft.mouseHandler.ypos() * (double) this.minecraft.getWindow()
|
||||
.getGuiScaledHeight() / (double) this.minecraft.getWindow()
|
||||
.getScreenHeight());
|
||||
|
||||
mx -= guiLeft + 35;
|
||||
my -= guiTop + 41;
|
||||
|
||||
hoveredCheck = false;
|
||||
hoveredEntry = -1;
|
||||
|
||||
if (mx > 0 && mx < 183 && my > 0 && my < 190) {
|
||||
hoveredCheck = mx < 20;
|
||||
int totalHeight = 0;
|
||||
for (int i = 0; i < currentEntries.size(); i++) {
|
||||
ClipboardEntry clipboardEntry = currentEntries.get(i);
|
||||
String text = clipboardEntry.text.getString();
|
||||
totalHeight += Math.max(12, font.split(Components.literal(text), 150)
|
||||
.size() * 9 + 3);
|
||||
|
||||
if (totalHeight > my) {
|
||||
hoveredEntry = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
hoveredEntry = currentEntries.size();
|
||||
}
|
||||
}
|
||||
|
||||
private String getCurrentEntryText() {
|
||||
return currentEntries.get(editingIndex).text.getString();
|
||||
}
|
||||
|
||||
private void setCurrentEntryText(String text) {
|
||||
currentEntries.get(editingIndex).text = Components.literal(text);
|
||||
}
|
||||
|
||||
private void setClipboard(String p_98148_) {
|
||||
if (minecraft != null)
|
||||
TextFieldHelper.setClipboardContents(minecraft, p_98148_);
|
||||
}
|
||||
|
||||
private String getClipboard() {
|
||||
return minecraft != null ? TextFieldHelper.getClipboardContents(minecraft) : "";
|
||||
}
|
||||
|
||||
private boolean validateTextForEntry(String newText) {
|
||||
int totalHeight = 0;
|
||||
for (int i = 0; i < currentEntries.size(); i++) {
|
||||
ClipboardEntry clipboardEntry = currentEntries.get(i);
|
||||
String text = i == editingIndex ? newText : clipboardEntry.text.getString();
|
||||
totalHeight += Math.max(12, font.split(Components.literal(text), 150)
|
||||
.size() * 9 + 3);
|
||||
}
|
||||
return totalHeight < 185;
|
||||
}
|
||||
|
||||
private int yOffsetOfEditingEntry() {
|
||||
int totalHeight = 0;
|
||||
for (int i = 0; i < currentEntries.size(); i++) {
|
||||
if (i == editingIndex)
|
||||
break;
|
||||
ClipboardEntry clipboardEntry = currentEntries.get(i);
|
||||
totalHeight += Math.max(12, font.split(clipboardEntry.text, 150)
|
||||
.size() * 9 + 3);
|
||||
}
|
||||
return totalHeight;
|
||||
}
|
||||
|
||||
private void changePage(boolean next) {
|
||||
int previously = currentPage;
|
||||
currentPage = Mth.clamp(currentPage + (next ? 1 : -1), 0, 50);
|
||||
if (currentPage == previously)
|
||||
return;
|
||||
editingIndex = -1;
|
||||
if (pages.size() <= currentPage)
|
||||
pages.add(new ArrayList<>());
|
||||
currentEntries = pages.get(currentPage);
|
||||
if (currentEntries.isEmpty()) {
|
||||
currentEntries.add(new ClipboardEntry(false, Components.empty()));
|
||||
editingIndex = 0;
|
||||
editContext.setCursorToEnd();
|
||||
clearDisplayCacheAfterChange();
|
||||
}
|
||||
|
||||
forward.visible = currentPage < 50;
|
||||
backward.visible = currentPage > 0;
|
||||
|
||||
if (next)
|
||||
return;
|
||||
if (pages.get(currentPage + 1)
|
||||
.stream()
|
||||
.allMatch(ce -> ce.text.getString()
|
||||
.isBlank()))
|
||||
pages.remove(currentPage + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindow(PoseStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
int x = guiLeft;
|
||||
int y = guiTop - 8;
|
||||
|
||||
AllGuiTextures.CLIPBOARD.render(ms, x, y);
|
||||
font.draw(ms, new TranslatableComponent("book.pageIndicator", currentPage + 1, getNumPages()), x + 150, y + 9,
|
||||
0x43ffffff);
|
||||
|
||||
for (int i = 0; i < currentEntries.size(); i++) {
|
||||
ClipboardEntry clipboardEntry = currentEntries.get(i);
|
||||
boolean checked = clipboardEntry.checked;
|
||||
|
||||
font.draw(ms, "\u25A1", x + 45, y + 51, checked ? 0x668D7F6B : 0xff8D7F6B);
|
||||
if (checked)
|
||||
font.draw(ms, "\u2714", x + 45, y + 50, 0x31B25D);
|
||||
|
||||
List<FormattedCharSequence> split = font.split(clipboardEntry.text, 150);
|
||||
if (split.isEmpty()) {
|
||||
y += 12;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (FormattedCharSequence sequence : split) {
|
||||
if (i != editingIndex)
|
||||
font.draw(ms, sequence, x + 58, y + 50, checked ? 0x31B25D : 0x311A00);
|
||||
y += 9;
|
||||
}
|
||||
y += 3;
|
||||
}
|
||||
|
||||
if (editingIndex == -1)
|
||||
return;
|
||||
|
||||
boolean checked = currentEntries.get(editingIndex).checked;
|
||||
|
||||
setFocused(null);
|
||||
DisplayCache cache = getDisplayCache();
|
||||
|
||||
for (LineInfo line : cache.lines)
|
||||
font.draw(ms, line.asComponent, line.x, line.y, checked ? 0x31B25D : 0x311A00);
|
||||
|
||||
renderHighlight(cache.selection);
|
||||
renderCursor(ms, cache.cursor, cache.cursorAtEnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed() {
|
||||
minecraft.keyboardHandler.setSendRepeatsToGui(false);
|
||||
pages.forEach(list -> list.removeIf(ce -> ce.text.getString()
|
||||
.isBlank()));
|
||||
pages.removeIf(List::isEmpty);
|
||||
|
||||
ClipboardEntry.saveAll(pages, item);
|
||||
ClipboardOverrides.switchTo(ClipboardType.WRITTEN, item);
|
||||
|
||||
for (int i = 0; i < pages.size(); i++)
|
||||
if (pages.get(i) == currentEntries)
|
||||
item.getTag()
|
||||
.putInt("PreviouslyOpenedPage", i);
|
||||
|
||||
if (pages.isEmpty())
|
||||
item.setTag(new CompoundTag());
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(new ClipboardEditPacket(targetSlot, item.getOrCreateTag()));
|
||||
super.removed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPauseScreen() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
if (pKeyCode == 266) {
|
||||
backward.onPress();
|
||||
return true;
|
||||
}
|
||||
if (pKeyCode == 267) {
|
||||
forward.onPress();
|
||||
return true;
|
||||
}
|
||||
if (editingIndex != -1 && pKeyCode != 256) {
|
||||
keyPressedWhileEditing(pKeyCode, pScanCode, pModifiers);
|
||||
clearDisplayCache();
|
||||
return true;
|
||||
}
|
||||
if (super.keyPressed(pKeyCode, pScanCode, pModifiers))
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char pCodePoint, int pModifiers) {
|
||||
if (super.charTyped(pCodePoint, pModifiers))
|
||||
return true;
|
||||
if (!SharedConstants.isAllowedChatCharacter(pCodePoint))
|
||||
return false;
|
||||
if (editingIndex == -1)
|
||||
return false;
|
||||
editContext.insertText(Character.toString(pCodePoint));
|
||||
clearDisplayCache();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean keyPressedWhileEditing(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
if (Screen.isSelectAll(pKeyCode)) {
|
||||
editContext.selectAll();
|
||||
return true;
|
||||
} else if (Screen.isCopy(pKeyCode)) {
|
||||
editContext.copy();
|
||||
return true;
|
||||
} else if (Screen.isPaste(pKeyCode)) {
|
||||
editContext.paste();
|
||||
return true;
|
||||
} else if (Screen.isCut(pKeyCode)) {
|
||||
editContext.cut();
|
||||
return true;
|
||||
} else {
|
||||
switch (pKeyCode) {
|
||||
case 257:
|
||||
case 335:
|
||||
if (hasShiftDown()) {
|
||||
editContext.insertText("\n");
|
||||
return true;
|
||||
} else if (!hasControlDown()) {
|
||||
if (currentEntries.size() <= editingIndex + 1
|
||||
|| !currentEntries.get(editingIndex + 1).text.getString()
|
||||
.isEmpty())
|
||||
currentEntries.add(editingIndex + 1, new ClipboardEntry(false, Components.empty()));
|
||||
editingIndex += 1;
|
||||
editContext.setCursorToEnd();
|
||||
if (validateTextForEntry(" "))
|
||||
return true;
|
||||
currentEntries.remove(editingIndex);
|
||||
editingIndex -= 1;
|
||||
editContext.setCursorToEnd();
|
||||
return true;
|
||||
}
|
||||
editingIndex = -1;
|
||||
return true;
|
||||
case 259:
|
||||
if (currentEntries.get(editingIndex).text.getString()
|
||||
.isEmpty() && currentEntries.size() > 1) {
|
||||
currentEntries.remove(editingIndex);
|
||||
editingIndex -= 1;
|
||||
editContext.setCursorToEnd();
|
||||
return true;
|
||||
} else if (hasControlDown()) {
|
||||
int prevPos = editContext.getCursorPos();
|
||||
editContext.moveByWords(-1);
|
||||
if (prevPos != editContext.getCursorPos())
|
||||
editContext.removeCharsFromCursor(prevPos - editContext.getCursorPos());
|
||||
return true;
|
||||
}
|
||||
editContext.removeCharsFromCursor(-1);
|
||||
return true;
|
||||
case 261:
|
||||
if (hasControlDown()) {
|
||||
int prevPos = editContext.getCursorPos();
|
||||
editContext.moveByWords(1);
|
||||
if (prevPos != editContext.getCursorPos())
|
||||
editContext.removeCharsFromCursor(prevPos - editContext.getCursorPos());
|
||||
return true;
|
||||
}
|
||||
editContext.removeCharsFromCursor(1);
|
||||
return true;
|
||||
case 262:
|
||||
if (hasControlDown()) {
|
||||
editContext.moveByWords(1, Screen.hasShiftDown());
|
||||
return true;
|
||||
}
|
||||
editContext.moveByChars(1, Screen.hasShiftDown());
|
||||
return true;
|
||||
case 263:
|
||||
if (hasControlDown()) {
|
||||
editContext.moveByWords(-1, Screen.hasShiftDown());
|
||||
return true;
|
||||
}
|
||||
editContext.moveByChars(-1, Screen.hasShiftDown());
|
||||
return true;
|
||||
case 264:
|
||||
keyDown();
|
||||
return true;
|
||||
case 265:
|
||||
keyUp();
|
||||
return true;
|
||||
case 268:
|
||||
keyHome();
|
||||
return true;
|
||||
case 269:
|
||||
keyEnd();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void keyUp() {
|
||||
changeLine(-1);
|
||||
}
|
||||
|
||||
private void keyDown() {
|
||||
changeLine(1);
|
||||
}
|
||||
|
||||
private void changeLine(int pYChange) {
|
||||
int i = editContext.getCursorPos();
|
||||
int j = getDisplayCache().changeLine(i, pYChange);
|
||||
editContext.setCursorPos(j, Screen.hasShiftDown());
|
||||
}
|
||||
|
||||
private void keyHome() {
|
||||
int i = editContext.getCursorPos();
|
||||
int j = getDisplayCache().findLineStart(i);
|
||||
editContext.setCursorPos(j, Screen.hasShiftDown());
|
||||
}
|
||||
|
||||
private void keyEnd() {
|
||||
DisplayCache cache = getDisplayCache();
|
||||
int i = editContext.getCursorPos();
|
||||
int j = cache.findLineEnd(i);
|
||||
editContext.setCursorPos(j, Screen.hasShiftDown());
|
||||
}
|
||||
|
||||
private void renderCursor(PoseStack pPoseStack, Pos2i pCursorPos, boolean pIsEndOfText) {
|
||||
if (frameTick / 6 % 2 != 0)
|
||||
return;
|
||||
pCursorPos = convertLocalToScreen(pCursorPos);
|
||||
if (!pIsEndOfText) {
|
||||
GuiComponent.fill(pPoseStack, pCursorPos.x, pCursorPos.y - 1, pCursorPos.x + 1, pCursorPos.y + 9,
|
||||
-16777216);
|
||||
} else {
|
||||
font.draw(pPoseStack, "_", (float) pCursorPos.x, (float) pCursorPos.y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderHighlight(Rect2i[] pSelected) {
|
||||
Tesselator tesselator = Tesselator.getInstance();
|
||||
BufferBuilder bufferbuilder = tesselator.getBuilder();
|
||||
RenderSystem.setShader(GameRenderer::getPositionShader);
|
||||
RenderSystem.setShaderColor(0.0F, 0.0F, 255.0F, 255.0F);
|
||||
RenderSystem.disableTexture();
|
||||
RenderSystem.enableColorLogicOp();
|
||||
RenderSystem.logicOp(GlStateManager.LogicOp.OR_REVERSE);
|
||||
bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
|
||||
|
||||
for (Rect2i rect2i : pSelected) {
|
||||
int i = rect2i.getX();
|
||||
int j = rect2i.getY();
|
||||
int k = i + rect2i.getWidth();
|
||||
int l = j + rect2i.getHeight();
|
||||
bufferbuilder.vertex((double) i, (double) l, 0.0D)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex((double) k, (double) l, 0.0D)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex((double) k, (double) j, 0.0D)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex((double) i, (double) j, 0.0D)
|
||||
.endVertex();
|
||||
}
|
||||
|
||||
tesselator.end();
|
||||
RenderSystem.disableColorLogicOp();
|
||||
RenderSystem.enableTexture();
|
||||
}
|
||||
|
||||
private Pos2i convertScreenToLocal(Pos2i pScreenPos) {
|
||||
return new Pos2i(pScreenPos.x - (width - 192) / 2 - 36 + 10, pScreenPos.y - 32 - 24 - yOffsetOfEditingEntry());
|
||||
}
|
||||
|
||||
private Pos2i convertLocalToScreen(Pos2i pLocalScreenPos) {
|
||||
return new Pos2i(pLocalScreenPos.x + (width - 192) / 2 + 36 - 10,
|
||||
pLocalScreenPos.y + 32 + 24 + yOffsetOfEditingEntry());
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
|
||||
if (super.mouseClicked(pMouseX, pMouseY, pButton))
|
||||
return true;
|
||||
if (pButton != 0)
|
||||
return true;
|
||||
|
||||
if (hoveredEntry != -1) {
|
||||
if (hoveredCheck) {
|
||||
editingIndex = -1;
|
||||
if (hoveredEntry < currentEntries.size())
|
||||
currentEntries.get(hoveredEntry).checked ^= true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hoveredEntry != editingIndex) {
|
||||
editingIndex = hoveredEntry;
|
||||
if (hoveredEntry >= currentEntries.size()) {
|
||||
currentEntries.add(new ClipboardEntry(false, Components.empty()));
|
||||
if (!validateTextForEntry(" ")) {
|
||||
currentEntries.remove(hoveredEntry);
|
||||
editingIndex = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
clearDisplayCacheAfterChange();
|
||||
}
|
||||
}
|
||||
|
||||
if (editingIndex == -1)
|
||||
return false;
|
||||
|
||||
long i = Util.getMillis();
|
||||
DisplayCache cache = getDisplayCache();
|
||||
int j = cache.getIndexAtPosition(font, convertScreenToLocal(new Pos2i((int) pMouseX, (int) pMouseY)));
|
||||
if (j >= 0) {
|
||||
if (j == lastIndex && i - lastClickTime < 250L) {
|
||||
if (!editContext.isSelecting()) {
|
||||
selectWord(j);
|
||||
} else {
|
||||
editContext.selectAll();
|
||||
}
|
||||
} else {
|
||||
editContext.setCursorPos(j, Screen.hasShiftDown());
|
||||
}
|
||||
|
||||
clearDisplayCache();
|
||||
}
|
||||
|
||||
lastIndex = j;
|
||||
lastClickTime = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void selectWord(int pIndex) {
|
||||
String s = getCurrentEntryText();
|
||||
editContext.setSelectionRange(StringSplitter.getWordPosition(s, -1, pIndex, false),
|
||||
StringSplitter.getWordPosition(s, 1, pIndex, false));
|
||||
}
|
||||
|
||||
public boolean mouseDragged(double pMouseX, double pMouseY, int pButton, double pDragX, double pDragY) {
|
||||
if (super.mouseDragged(pMouseX, pMouseY, pButton, pDragX, pDragY))
|
||||
return true;
|
||||
if (pButton != 0)
|
||||
return true;
|
||||
if (editingIndex == -1)
|
||||
return false;
|
||||
|
||||
DisplayCache cache = getDisplayCache();
|
||||
int i = cache.getIndexAtPosition(font, convertScreenToLocal(new Pos2i((int) pMouseX, (int) pMouseY)));
|
||||
editContext.setCursorPos(i, true);
|
||||
clearDisplayCache();
|
||||
return true;
|
||||
}
|
||||
|
||||
private DisplayCache getDisplayCache() {
|
||||
if (displayCache == null)
|
||||
displayCache = rebuildDisplayCache();
|
||||
return displayCache;
|
||||
}
|
||||
|
||||
private void clearDisplayCache() {
|
||||
displayCache = null;
|
||||
}
|
||||
|
||||
private void clearDisplayCacheAfterChange() {
|
||||
editContext.setCursorToEnd();
|
||||
clearDisplayCache();
|
||||
}
|
||||
|
||||
private DisplayCache rebuildDisplayCache() {
|
||||
String s = getCurrentEntryText();
|
||||
if (s.isEmpty())
|
||||
return DisplayCache.EMPTY;
|
||||
|
||||
int i = editContext.getCursorPos();
|
||||
int j = editContext.getSelectionPos();
|
||||
IntList intlist = new IntArrayList();
|
||||
List<LineInfo> list = Lists.newArrayList();
|
||||
MutableInt mutableint = new MutableInt();
|
||||
MutableBoolean mutableboolean = new MutableBoolean();
|
||||
StringSplitter stringsplitter = font.getSplitter();
|
||||
stringsplitter.splitLines(s, 150, Style.EMPTY, true, (p_98132_, p_98133_, p_98134_) -> {
|
||||
int k3 = mutableint.getAndIncrement();
|
||||
String s2 = s.substring(p_98133_, p_98134_);
|
||||
mutableboolean.setValue(s2.endsWith("\n"));
|
||||
String s3 = StringUtils.stripEnd(s2, " \n");
|
||||
int l3 = k3 * 9;
|
||||
Pos2i pos1 = convertLocalToScreen(new Pos2i(0, l3));
|
||||
intlist.add(p_98133_);
|
||||
list.add(new LineInfo(p_98132_, s3, pos1.x, pos1.y));
|
||||
});
|
||||
|
||||
int[] aint = intlist.toIntArray();
|
||||
boolean flag = i == s.length();
|
||||
Pos2i pos;
|
||||
if (flag && mutableboolean.isTrue()) {
|
||||
pos = new Pos2i(0, list.size() * 9);
|
||||
} else {
|
||||
int k = findLineFromPos(aint, i);
|
||||
int l = font.width(s.substring(aint[k], i));
|
||||
pos = new Pos2i(l, k * 9);
|
||||
}
|
||||
|
||||
List<Rect2i> list1 = Lists.newArrayList();
|
||||
if (i != j) {
|
||||
int l2 = Math.min(i, j);
|
||||
int i1 = Math.max(i, j);
|
||||
int j1 = findLineFromPos(aint, l2);
|
||||
int k1 = findLineFromPos(aint, i1);
|
||||
if (j1 == k1) {
|
||||
int l1 = j1 * 9;
|
||||
int i2 = aint[j1];
|
||||
list1.add(createPartialLineSelection(s, stringsplitter, l2, i1, l1, i2));
|
||||
} else {
|
||||
int i3 = j1 + 1 > aint.length ? s.length() : aint[j1 + 1];
|
||||
list1.add(createPartialLineSelection(s, stringsplitter, l2, i3, j1 * 9, aint[j1]));
|
||||
|
||||
for (int j3 = j1 + 1; j3 < k1; ++j3) {
|
||||
int j2 = j3 * 9;
|
||||
String s1 = s.substring(aint[j3], aint[j3 + 1]);
|
||||
int k2 = (int) stringsplitter.stringWidth(s1);
|
||||
list1.add(createSelection(new Pos2i(0, j2), new Pos2i(k2, j2 + 9)));
|
||||
}
|
||||
|
||||
list1.add(createPartialLineSelection(s, stringsplitter, aint[k1], i1, k1 * 9, aint[k1]));
|
||||
}
|
||||
}
|
||||
|
||||
return new DisplayCache(s, pos, flag, aint, list.toArray(new LineInfo[0]), list1.toArray(new Rect2i[0]));
|
||||
}
|
||||
|
||||
static int findLineFromPos(int[] pLineStarts, int pFind) {
|
||||
int i = Arrays.binarySearch(pLineStarts, pFind);
|
||||
return i < 0 ? -(i + 2) : i;
|
||||
}
|
||||
|
||||
private Rect2i createPartialLineSelection(String pInput, StringSplitter pSplitter, int p_98122_, int p_98123_,
|
||||
int p_98124_, int p_98125_) {
|
||||
String s = pInput.substring(p_98125_, p_98122_);
|
||||
String s1 = pInput.substring(p_98125_, p_98123_);
|
||||
Pos2i firstPos = new Pos2i((int) pSplitter.stringWidth(s), p_98124_);
|
||||
Pos2i secondPos = new Pos2i((int) pSplitter.stringWidth(s1), p_98124_ + 9);
|
||||
return createSelection(firstPos, secondPos);
|
||||
}
|
||||
|
||||
private Rect2i createSelection(Pos2i pCorner1, Pos2i pCorner2) {
|
||||
Pos2i firstPos = convertLocalToScreen(pCorner1);
|
||||
Pos2i secondPos = convertLocalToScreen(pCorner2);
|
||||
int i = Math.min(firstPos.x, secondPos.x);
|
||||
int j = Math.max(firstPos.x, secondPos.x);
|
||||
int k = Math.min(firstPos.y, secondPos.y);
|
||||
int l = Math.max(firstPos.y, secondPos.y);
|
||||
return new Rect2i(i, k, j - i, l - k);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class DisplayCache {
|
||||
static final DisplayCache EMPTY = new DisplayCache("", new Pos2i(0, 0), true, new int[] { 0 },
|
||||
new LineInfo[] { new LineInfo(Style.EMPTY, "", 0, 0) }, new Rect2i[0]);
|
||||
private final String fullText;
|
||||
final Pos2i cursor;
|
||||
final boolean cursorAtEnd;
|
||||
private final int[] lineStarts;
|
||||
final LineInfo[] lines;
|
||||
final Rect2i[] selection;
|
||||
|
||||
public DisplayCache(String pFullText, Pos2i pCursor, boolean pCursorAtEnd, int[] pLineStarts, LineInfo[] pLines,
|
||||
Rect2i[] pSelection) {
|
||||
fullText = pFullText;
|
||||
cursor = pCursor;
|
||||
cursorAtEnd = pCursorAtEnd;
|
||||
lineStarts = pLineStarts;
|
||||
lines = pLines;
|
||||
selection = pSelection;
|
||||
}
|
||||
|
||||
public int getIndexAtPosition(Font pFont, Pos2i pCursorPosition) {
|
||||
int i = pCursorPosition.y / 9;
|
||||
if (i < 0)
|
||||
return 0;
|
||||
if (i >= lines.length)
|
||||
return fullText.length();
|
||||
LineInfo line = lines[i];
|
||||
return lineStarts[i] + pFont.getSplitter()
|
||||
.plainIndexAtWidth(line.contents, pCursorPosition.x, line.style);
|
||||
}
|
||||
|
||||
public int changeLine(int pXChange, int pYChange) {
|
||||
int i = findLineFromPos(lineStarts, pXChange);
|
||||
int j = i + pYChange;
|
||||
int k;
|
||||
if (0 <= j && j < lineStarts.length) {
|
||||
int l = pXChange - lineStarts[i];
|
||||
int i1 = lines[j].contents.length();
|
||||
k = lineStarts[j] + Math.min(l, i1);
|
||||
} else {
|
||||
k = pXChange;
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
public int findLineStart(int pLine) {
|
||||
int i = findLineFromPos(lineStarts, pLine);
|
||||
return lineStarts[i];
|
||||
}
|
||||
|
||||
public int findLineEnd(int pLine) {
|
||||
int i = findLineFromPos(lineStarts, pLine);
|
||||
return lineStarts[i] + lines[i].contents.length();
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class LineInfo {
|
||||
final Style style;
|
||||
final String contents;
|
||||
final Component asComponent;
|
||||
final int x;
|
||||
final int y;
|
||||
|
||||
public LineInfo(Style pStyle, String pContents, int pX, int pY) {
|
||||
style = pStyle;
|
||||
contents = pContents;
|
||||
x = pX;
|
||||
y = pY;
|
||||
asComponent = (new TextComponent(pContents)).setStyle(pStyle);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class Pos2i {
|
||||
public final int x;
|
||||
public final int y;
|
||||
|
||||
Pos2i(int pX, int pY) {
|
||||
x = pX;
|
||||
y = pY;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.simibubi.create.content.curiosities.clipboard;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.BookEditScreen;
|
||||
|
||||
public class ClipboardScreenHelper {
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -76,6 +76,8 @@ public enum AllGuiTextures implements ScreenElement {
|
|||
|
||||
LINKED_CONTROLLER("curiosities_2", 179, 109),
|
||||
BLUEPRINT("curiosities_2", 0, 109, 179, 109),
|
||||
|
||||
CLIPBOARD("clipboard", 0, 0, 256, 256),
|
||||
|
||||
PROJECTOR("projector", 235, 185),
|
||||
PROJECTOR_FILTER_STRENGTH("projector", 0, 14, 162, 22),
|
||||
|
|
|
@ -127,6 +127,8 @@ public class AllIcons implements ScreenElement {
|
|||
I_PATTERN_CHANCE_75 = next(),
|
||||
I_FOLLOW_DIAGONAL = next(),
|
||||
I_FOLLOW_MATERIAL = next(),
|
||||
|
||||
I_CLEAR_CHECKED = next(),
|
||||
|
||||
I_SCHEMATIC = newRow(),
|
||||
I_SEQ_REPEAT = next(),
|
||||
|
|
|
@ -37,6 +37,7 @@ import com.simibubi.create.content.contraptions.relays.advanced.sequencer.Config
|
|||
import com.simibubi.create.content.contraptions.relays.gauge.GaugeObservedPacket;
|
||||
import com.simibubi.create.content.curiosities.armor.NetheriteDivingHandler;
|
||||
import com.simibubi.create.content.curiosities.bell.SoulPulseEffectPacket;
|
||||
import com.simibubi.create.content.curiosities.clipboard.ClipboardEditPacket;
|
||||
import com.simibubi.create.content.curiosities.symmetry.ConfigureSymmetryWandPacket;
|
||||
import com.simibubi.create.content.curiosities.symmetry.SymmetryEffectPacket;
|
||||
import com.simibubi.create.content.curiosities.toolbox.ToolboxDisposeAllPacket;
|
||||
|
@ -157,6 +158,7 @@ public enum AllPackets {
|
|||
REQUEST_FLOOR_LIST(ElevatorFloorListPacket.RequestFloorList.class, ElevatorFloorListPacket.RequestFloorList::new,
|
||||
PLAY_TO_SERVER),
|
||||
ELEVATOR_SET_FLOOR(ElevatorTargetFloorPacket.class, ElevatorTargetFloorPacket::new, PLAY_TO_SERVER),
|
||||
CLIPBOARD_EDIT(ClipboardEditPacket.class, ClipboardEditPacket::new, PLAY_TO_SERVER),
|
||||
|
||||
// Server to Client
|
||||
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),
|
||||
|
|
|
@ -272,6 +272,8 @@
|
|||
"create.gui.sequenced_gearshift.speed.back": "Input speed, Reversed",
|
||||
"create.gui.sequenced_gearshift.speed.back_fast": "Double speed, Reversed",
|
||||
|
||||
"create.gui.clipboard.erase_checked": "Erase checked items",
|
||||
|
||||
"create.schematicAndQuill.dimensions": "Schematic Size: %1$sx%2$sx%3$s",
|
||||
"create.schematicAndQuill.firstPos": "First position set.",
|
||||
"create.schematicAndQuill.secondPos": "Second position set.",
|
||||
|
|
BIN
src/main/resources/assets/create/textures/gui/clipboard.pdn
Normal file
BIN
src/main/resources/assets/create/textures/gui/clipboard.pdn
Normal file
Binary file not shown.
BIN
src/main/resources/assets/create/textures/gui/clipboard.png
Normal file
BIN
src/main/resources/assets/create/textures/gui/clipboard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
BIN
src/main/resources/assets/create/textures/item/clipboard.png
Normal file
BIN
src/main/resources/assets/create/textures/item/clipboard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 290 B |
Binary file not shown.
After Width: | Height: | Size: 332 B |
Binary file not shown.
After Width: | Height: | Size: 281 B |
Loading…
Reference in a new issue