mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-28 07:56:44 +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
|
5616dda664dd106d576848124fc0fc1de18d0fd3 assets/create/blockstates/yellow_valve_handle.json
|
||||||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
|
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
|
||||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||||
f1bedeb51c35e70a2247178634e61ea637a6622e assets/create/lang/en_ud.json
|
0f4e5a2fc58580df5b156fdac438ddeb6b57e386 assets/create/lang/en_ud.json
|
||||||
59fd557ef593efa3c7b783195ec5dc789eae1834 assets/create/lang/en_us.json
|
85d790bedbdc65bb6e6377edcc63e7b00455e879 assets/create/lang/en_us.json
|
||||||
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
||||||
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
||||||
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.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
|
87637b39c3a5a386457d52b37eb65f1c4bcabaf0 assets/create/models/item/chocolate_glazed_berries.json
|
||||||
fe67c3f380d17735a9436a4579a8be1a02b8e4a0 assets/create/models/item/chute.json
|
fe67c3f380d17735a9436a4579a8be1a02b8e4a0 assets/create/models/item/chute.json
|
||||||
6680a68526576ded5dac2aa3bc9fb9de3e744146 assets/create/models/item/cinder_flour.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
|
c1da21be9f1af4f7a2ef4ec9cd92195d65ada316 assets/create/models/item/clockwork_bearing.json
|
||||||
0a2a0f0aafeab0088172f77afd40c1fa2cc1f2b8 assets/create/models/item/clutch.json
|
0a2a0f0aafeab0088172f77afd40c1fa2cc1f2b8 assets/create/models/item/clutch.json
|
||||||
dcb09deae110077bcddf090996b51cc66e9a7de3 assets/create/models/item/cogwheel.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.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.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.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": "\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_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",
|
"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.chocolate_glazed_berries": "Chocolate Glazed Berries",
|
||||||
"item.create.chromatic_compound": "Chromatic Compound",
|
"item.create.chromatic_compound": "Chromatic Compound",
|
||||||
"item.create.cinder_flour": "Cinder Flour",
|
"item.create.cinder_flour": "Cinder Flour",
|
||||||
|
"item.create.clipboard": "Clipboard",
|
||||||
"item.create.copper_backtank": "Copper Backtank",
|
"item.create.copper_backtank": "Copper Backtank",
|
||||||
"item.create.copper_backtank_placeable": "Copper Backtank Placeable",
|
"item.create.copper_backtank_placeable": "Copper Backtank Placeable",
|
||||||
"item.create.copper_diving_boots": "Copper Diving Boots",
|
"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.forward_fast": "Double speed, Forwards",
|
||||||
"create.gui.sequenced_gearshift.speed.back": "Input speed, Reversed",
|
"create.gui.sequenced_gearshift.speed.back": "Input speed, Reversed",
|
||||||
"create.gui.sequenced_gearshift.speed.back_fast": "Double 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.dimensions": "Schematic Size: %1$sx%2$sx%3$s",
|
||||||
"create.schematicAndQuill.firstPos": "First position set.",
|
"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.BacktankItem.BacktankBlockItem;
|
||||||
import com.simibubi.create.content.curiosities.armor.DivingBootsItem;
|
import com.simibubi.create.content.curiosities.armor.DivingBootsItem;
|
||||||
import com.simibubi.create.content.curiosities.armor.DivingHelmetItem;
|
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.symmetry.SymmetryWandItem;
|
||||||
import com.simibubi.create.content.curiosities.tools.BlueprintItem;
|
import com.simibubi.create.content.curiosities.tools.BlueprintItem;
|
||||||
import com.simibubi.create.content.curiosities.tools.ExtendoGripItem;
|
import com.simibubi.create.content.curiosities.tools.ExtendoGripItem;
|
||||||
|
@ -72,7 +74,10 @@ public class AllItems {
|
||||||
REGISTRATE.creativeModeTab(() -> AllCreativeModeTabs.BASE_CREATIVE_TAB);
|
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 =
|
public static final ItemEntry<Item> WHEAT_FLOUR =
|
||||||
taggedIngredient("wheat_flour", forgeItemTag("flour/wheat"), forgeItemTag("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 {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -77,6 +77,8 @@ public enum AllGuiTextures implements ScreenElement {
|
||||||
LINKED_CONTROLLER("curiosities_2", 179, 109),
|
LINKED_CONTROLLER("curiosities_2", 179, 109),
|
||||||
BLUEPRINT("curiosities_2", 0, 109, 179, 109),
|
BLUEPRINT("curiosities_2", 0, 109, 179, 109),
|
||||||
|
|
||||||
|
CLIPBOARD("clipboard", 0, 0, 256, 256),
|
||||||
|
|
||||||
PROJECTOR("projector", 235, 185),
|
PROJECTOR("projector", 235, 185),
|
||||||
PROJECTOR_FILTER_STRENGTH("projector", 0, 14, 162, 22),
|
PROJECTOR_FILTER_STRENGTH("projector", 0, 14, 162, 22),
|
||||||
PROJECTOR_FILTER("projector", 0, 36, 162, 22),
|
PROJECTOR_FILTER("projector", 0, 36, 162, 22),
|
||||||
|
|
|
@ -128,6 +128,8 @@ public class AllIcons implements ScreenElement {
|
||||||
I_FOLLOW_DIAGONAL = next(),
|
I_FOLLOW_DIAGONAL = next(),
|
||||||
I_FOLLOW_MATERIAL = next(),
|
I_FOLLOW_MATERIAL = next(),
|
||||||
|
|
||||||
|
I_CLEAR_CHECKED = next(),
|
||||||
|
|
||||||
I_SCHEMATIC = newRow(),
|
I_SCHEMATIC = newRow(),
|
||||||
I_SEQ_REPEAT = next(),
|
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.contraptions.relays.gauge.GaugeObservedPacket;
|
||||||
import com.simibubi.create.content.curiosities.armor.NetheriteDivingHandler;
|
import com.simibubi.create.content.curiosities.armor.NetheriteDivingHandler;
|
||||||
import com.simibubi.create.content.curiosities.bell.SoulPulseEffectPacket;
|
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.ConfigureSymmetryWandPacket;
|
||||||
import com.simibubi.create.content.curiosities.symmetry.SymmetryEffectPacket;
|
import com.simibubi.create.content.curiosities.symmetry.SymmetryEffectPacket;
|
||||||
import com.simibubi.create.content.curiosities.toolbox.ToolboxDisposeAllPacket;
|
import com.simibubi.create.content.curiosities.toolbox.ToolboxDisposeAllPacket;
|
||||||
|
@ -157,6 +158,7 @@ public enum AllPackets {
|
||||||
REQUEST_FLOOR_LIST(ElevatorFloorListPacket.RequestFloorList.class, ElevatorFloorListPacket.RequestFloorList::new,
|
REQUEST_FLOOR_LIST(ElevatorFloorListPacket.RequestFloorList.class, ElevatorFloorListPacket.RequestFloorList::new,
|
||||||
PLAY_TO_SERVER),
|
PLAY_TO_SERVER),
|
||||||
ELEVATOR_SET_FLOOR(ElevatorTargetFloorPacket.class, ElevatorTargetFloorPacket::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
|
// Server to Client
|
||||||
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_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": "Input speed, Reversed",
|
||||||
"create.gui.sequenced_gearshift.speed.back_fast": "Double 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.dimensions": "Schematic Size: %1$sx%2$sx%3$s",
|
||||||
"create.schematicAndQuill.firstPos": "First position set.",
|
"create.schematicAndQuill.firstPos": "First position set.",
|
||||||
"create.schematicAndQuill.secondPos": "Second 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