Skip to content

Commit

Permalink
[ci skip] Add ClientTooltipComponentRegistry for custom tooltips (#475)
Browse files Browse the repository at this point in the history
* Add ClientTooltipComponentRegistry for custom tooltips (#463)

Signed-off-by: Sergey Shatunov <[email protected]>
Signed-off-by: shedaniel <[email protected]>

* Fix testmod for client tooltip components

Signed-off-by: shedaniel <[email protected]>

---------

Signed-off-by: Sergey Shatunov <[email protected]>
Signed-off-by: shedaniel <[email protected]>
Co-authored-by: Sergey Shatunov <[email protected]>
  • Loading branch information
shedaniel and Prototik authored Feb 6, 2024
1 parent 9851188 commit b26347a
Show file tree
Hide file tree
Showing 6 changed files with 237 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,42 @@
/*
* 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
@@ -0,0 +1,69 @@
/*
* 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 dev.architectury.platform.forge.EventBuses;
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 net.minecraftforge.client.event.RegisterClientTooltipComponentFactoriesEvent;
import net.minecraftforge.eventbus.api.EventPriority;
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<Entry<?>> entries = new ArrayList<>();

static {
EventBuses.onRegistered("architectury", bus -> {
bus.<RegisterClientTooltipComponentFactoriesEvent>addListener(EventPriority.HIGH, event -> {
if (entries != null) {
for (Entry<?> entry : entries) {
Entry<TooltipComponent> casted = (Entry<TooltipComponent>) entry;
event.register(casted.clazz(), casted.factory());
}

entries = null;
}
});
});
}

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

public record Entry<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 @@ -34,6 +34,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 dev.architectury.test.tab.TestCreativeTabs;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
Expand Down Expand Up @@ -127,6 +128,9 @@ public TestInt(int value) {
}
});

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

public static final RegistrySupplier<Block> TEST_BLOCK = BLOCKS.register("test_block", () ->
new Block(BlockBehaviour.Properties.copy(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,69 @@
/*
* 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 com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.client.renderer.entity.ItemRenderer;
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, PoseStack poseStack, ItemRenderer itemRenderer, int blitOffset) {
poseStack.pushPose();
poseStack.translate(0, 0, blitOffset);
font.draw(poseStack, "Count: " + component.count, x + getWidth(font) / 2, y + (getHeight() - font.lineHeight) / 2, 0xFF00FF00);
poseStack.popPose();
}
}
}

0 comments on commit b26347a

Please sign in to comment.