TooltipComponent API (#1695)

* TooltipComponent API

* Add warning
This commit is contained in:
Technici4n 2021-10-07 13:21:21 +02:00 committed by modmuss50
parent 6eb8b35a31
commit e1a2e51818
6 changed files with 197 additions and 2 deletions

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.api.client.rendering.v1;
import org.jetbrains.annotations.Nullable;
import net.minecraft.client.gui.tooltip.TooltipComponent;
import net.minecraft.item.Item;
import net.minecraft.client.item.TooltipData;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
/**
* Allows registering a mapping from {@link TooltipData} to {@link TooltipComponent}.
* This allows custom tooltips for items: first, override {@link Item#getTooltipData} and return a custom {@code TooltipData}.
* Second, register a listener to this event and convert the data to your component implementation if it's an instance of your data class.
*
* <p>Note that failure to map some data to a component will throw an exception,
* so make sure that any data you return in {@link Item#getTooltipData} will be handled by one of the callbacks.
*/
@Environment(EnvType.CLIENT)
public interface TooltipComponentCallback {
Event<TooltipComponentCallback> EVENT = EventFactory.createArrayBacked(TooltipComponentCallback.class, listeners -> data -> {
for (TooltipComponentCallback listener : listeners) {
TooltipComponent component = listener.getComponent(data);
if (component != null) {
return component;
}
}
return null;
});
/**
* Return the tooltip component for the passed data, or null if none is available.
*/
@Nullable
TooltipComponent getComponent(TooltipData data);
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.client.rendering;
import java.util.List;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.tooltip.TooltipComponent;
import net.minecraft.client.item.TooltipData;
import net.fabricmc.fabric.api.client.rendering.v1.TooltipComponentCallback;
@Mixin(Screen.class)
public class ScreenMixin {
// Synthetic lambda body in renderTooltip
@Inject(at = @At("HEAD"), method = "method_32635(Ljava/util/List;Lnet/minecraft/client/item/TooltipData;)V", cancellable = true)
private static void injectRenderTooltipLambda(List<TooltipComponent> components, TooltipData data, CallbackInfo ci) {
TooltipComponent component = TooltipComponentCallback.EVENT.invoker().getComponent(data);
if (component != null) {
components.add(1, component);
ci.cancel();
}
}
}

View file

@ -13,7 +13,8 @@
"EntityModelsMixin", "EntityModelsMixin",
"LivingEntityRendererAccessor", "LivingEntityRendererAccessor",
"MixinBlockEntityRenderers", "MixinBlockEntityRenderers",
"MixinEntityRenderers" "MixinEntityRenderers",
"ScreenMixin"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.test.rendering;
import java.util.Optional;
import net.minecraft.client.item.TooltipData;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.fabricmc.api.ModInitializer;
public class TooltipComponentTestInit implements ModInitializer {
public static Item CUSTOM_TOOLTIP_ITEM = new CustomTooltipItem();
@Override
public void onInitialize() {
Registry.register(Registry.ITEM, new Identifier("fabric-rendering-v1-testmod", "custom_tooltip"), CUSTOM_TOOLTIP_ITEM);
}
private static class CustomTooltipItem extends Item {
CustomTooltipItem() {
super(new Settings().group(ItemGroup.MISC));
}
@Override
public Optional<TooltipData> getTooltipData(ItemStack stack) {
return Optional.of(new Data(stack.getTranslationKey()));
}
}
public record Data(String string) implements TooltipData { }
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.test.rendering.client;
import net.minecraft.client.gui.tooltip.TooltipComponent;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Style;
import net.minecraft.util.Formatting;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendering.v1.TooltipComponentCallback;
import net.fabricmc.fabric.test.rendering.TooltipComponentTestInit;
public class TooltipComponentTests implements ClientModInitializer {
@Override
public void onInitializeClient() {
TooltipComponentCallback.EVENT.register(data -> {
if (data instanceof TooltipComponentTestInit.Data d) {
return TooltipComponent.of(new LiteralText(d.string()).setStyle(Style.EMPTY.withColor(Formatting.GREEN)).asOrderedText());
}
return null;
});
}
}

View file

@ -9,10 +9,14 @@
"fabric-rendering-v1": "*" "fabric-rendering-v1": "*"
}, },
"entrypoints": { "entrypoints": {
"main": [
"net.fabricmc.fabric.test.rendering.TooltipComponentTestInit"
],
"client": [ "client": [
"net.fabricmc.fabric.test.rendering.client.WorldRenderEventsTests", "net.fabricmc.fabric.test.rendering.client.WorldRenderEventsTests",
"net.fabricmc.fabric.test.rendering.client.ArmorRenderingTests", "net.fabricmc.fabric.test.rendering.client.ArmorRenderingTests",
"net.fabricmc.fabric.test.rendering.client.FeatureRendererTest" "net.fabricmc.fabric.test.rendering.client.FeatureRendererTest",
"net.fabricmc.fabric.test.rendering.client.TooltipComponentTests"
] ]
} }
} }