Skip to content

Commit

Permalink
Add ClientTooltipComponentRegistry for custom tooltips (#463)
Browse files Browse the repository at this point in the history
Signed-off-by: Sergey Shatunov <[email protected]>
  • Loading branch information
Prototik committed Jan 9, 2024
1 parent a4cbdb3 commit fd7e62b
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package dev.architectury.registry.client.gui;

import dev.architectury.injectables.annotations.ExpectPlatform;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.world.inventory.tooltip.TooltipComponent;

import java.util.function.Function;

/**
* Registry for {@link ClientTooltipComponent} factories
*/
@Environment(EnvType.CLIENT)
public final class ClientTooltipComponentRegistry {
private ClientTooltipComponentRegistry() {
}

/**
* Allows users to register custom {@link ClientTooltipComponent}
* factories for their {@link TooltipComponent} types.
*
* @param clazz class of {@link T}
* @param factory factory to create instances of {@link ClientTooltipComponent} from {@link T}
* @param <T> the type of {@link TooltipComponent} factory
*/
@ExpectPlatform
public static <T extends TooltipComponent> void register(Class<T> clazz, Function<? super T, ? extends ClientTooltipComponent> factory) {
throw new AssertionError();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package dev.architectury.registry.client.gui.fabric;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.rendering.v1.TooltipComponentCallback;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import org.jetbrains.annotations.ApiStatus;

import java.util.function.Function;

@Environment(EnvType.CLIENT)
@ApiStatus.Internal
public class ClientTooltipComponentRegistryImpl {

public static <T extends TooltipComponent> void register(Class<T> clazz, Function<? super T, ? extends ClientTooltipComponent> factory) {
TooltipComponentCallback.EVENT.register((tooltipComponent) -> {
if (clazz.isInstance(tooltipComponent)) {
return factory.apply(clazz.cast(tooltipComponent));
}
return null;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@
import dev.architectury.impl.ScreenAccessImpl;
import dev.architectury.impl.TooltipEventColorContextImpl;
import dev.architectury.impl.TooltipEventPositionContextImpl;
import dev.architectury.registry.client.gui.forge.ClientTooltipComponentRegistryImpl;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.network.chat.Component;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.*;
Expand Down Expand Up @@ -336,5 +338,14 @@ public static void event(FMLClientSetupEvent event) {
public static void event(RegisterShadersEvent event) {
ClientReloadShadersEvent.EVENT.invoker().reload(event.getResourceProvider(), event::registerShader);
}

@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(RegisterClientTooltipComponentFactoriesEvent event) {
ClientTooltipComponentRegistryImpl.consume(factory -> registerTooltipComponent(factory, event));
}

private static <T extends TooltipComponent> void registerTooltipComponent(ClientTooltipComponentRegistryImpl.Factory<T> factory, RegisterClientTooltipComponentFactoriesEvent event) {
event.register(factory.clazz(), factory.factory());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package dev.architectury.registry.client.gui.forge;

import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

@OnlyIn(Dist.CLIENT)
@ApiStatus.Internal
public class ClientTooltipComponentRegistryImpl {
@Nullable
private static List<Factory<?>> FACTORIES = new ArrayList<>();

public static void consume(Consumer<? super Factory<?>> consumer) {
if (FACTORIES != null) {
FACTORIES.forEach(consumer);
FACTORIES = null;
}
}

public static <T extends TooltipComponent> void register(Class<T> clazz, Function<? super T, ? extends ClientTooltipComponent> factory) {
if (FACTORIES == null) {
throw new IllegalStateException("Cannot register ClientTooltipComponent factory when factories are already aggregated!");
}
FACTORIES.add(new Factory<>(clazz, factory));
}

public record Factory<T extends TooltipComponent>(
Class<T> clazz, Function<? super T, ? extends ClientTooltipComponent> factory
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package dev.architectury.test;

import dev.architectury.event.events.client.ClientLifecycleEvent;
import dev.architectury.registry.client.gui.ClientTooltipComponentRegistry;
import dev.architectury.registry.client.level.entity.EntityRendererRegistry;
import dev.architectury.test.debug.ConsoleMessageSink;
import dev.architectury.test.debug.MessageSink;
Expand All @@ -33,6 +34,7 @@
import dev.architectury.test.particle.TestParticles;
import dev.architectury.test.registry.TestRegistries;
import dev.architectury.test.registry.client.TestKeybinds;
import dev.architectury.test.registry.objects.ItemWithTooltip;
import dev.architectury.test.tags.TestTags;
import dev.architectury.test.trade.TestTrades;
import dev.architectury.test.worldgen.TestWorldGeneration;
Expand Down Expand Up @@ -72,6 +74,7 @@ public static void initializeClient() {
TestModNet.initializeClient();
EntityRendererRegistry.register(TestRegistries.TEST_ENTITY, CowRenderer::new);
EntityRendererRegistry.register(TestRegistries.TEST_ENTITY_2, CowRenderer::new);
ClientTooltipComponentRegistry.register(ItemWithTooltip.MyTooltipComponent.class, ItemWithTooltip.MyClientTooltipComponent::new);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import dev.architectury.test.entity.TestEntity;
import dev.architectury.test.recipes.TestRecipeSerializer;
import dev.architectury.test.registry.objects.EquippableTickingItem;
import dev.architectury.test.registry.objects.ItemWithTooltip;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
Expand Down Expand Up @@ -135,6 +136,9 @@ public TestInt(int value) {
}
});

public static final RegistrySupplier<ItemWithTooltip> TEST_TOOLTIP = ITEMS.register("test_tooltip",
() -> new ItemWithTooltip(new Item.Properties().arch$tab(TestRegistries.TEST_TAB)));

public static final RegistrySupplier<Block> TEST_BLOCK = BLOCKS.register("test_block", () ->
new Block(BlockBehaviour.Properties.ofLegacyCopy(Blocks.STONE)));
public static final RegistrySupplier<Block> COLLISION_BLOCK = BLOCKS.register("collision_block", () ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package dev.architectury.test.registry.objects;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;

import java.util.Optional;

public class ItemWithTooltip extends Item {
public ItemWithTooltip(Properties properties) {
super(properties);
}

@Override
public @NotNull Optional<TooltipComponent> getTooltipImage(ItemStack itemStack) {
return Optional.of(new MyTooltipComponent(itemStack.getCount()));
}

public record MyTooltipComponent(int count) implements TooltipComponent {

}

@Environment(EnvType.CLIENT)
public record MyClientTooltipComponent(MyTooltipComponent component) implements ClientTooltipComponent {
@Override
public int getHeight() {
return 100;
}

@Override
public int getWidth(Font font) {
return 100;
}

@Override
public void renderImage(Font font, int x, int y, GuiGraphics guiGraphics) {
guiGraphics.drawString(font, "Count: " + component.count, x + getWidth(font) / 2, y + (getHeight() - font.lineHeight) / 2, 0xFF00FF00);
}
}
}

0 comments on commit fd7e62b

Please sign in to comment.