-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
71ef2e0
commit bdf4234
Showing
4 changed files
with
344 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
154 changes: 154 additions & 0 deletions
154
src/main/java/com/gtnewhorizon/gtnhlib/client/event/RenderTooltipEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package com.gtnewhorizon.gtnhlib.client.event; | ||
|
||
import java.util.List; | ||
import java.util.function.Consumer; | ||
|
||
import javax.annotation.Nonnull; | ||
import javax.annotation.Nullable; | ||
|
||
import net.minecraft.client.gui.FontRenderer; | ||
import net.minecraft.client.gui.Gui; | ||
import net.minecraft.client.gui.GuiScreen; | ||
import net.minecraft.client.renderer.entity.RenderItem; | ||
import net.minecraft.item.Item; | ||
import net.minecraft.item.ItemStack; | ||
import net.minecraftforge.common.MinecraftForge; | ||
import net.minecraftforge.event.entity.player.ItemTooltipEvent; | ||
|
||
import org.lwjgl.opengl.GL11; | ||
import org.lwjgl.opengl.GL12; | ||
|
||
import cpw.mods.fml.common.eventhandler.Cancelable; | ||
import cpw.mods.fml.common.eventhandler.Event; | ||
|
||
/** | ||
* RenderTooltipEvent is fired when a tooltip is about to be rendered. With this event you can modify colors, | ||
* coordinates, font or replace the renderer completely. To stop the tooltip from rendering at all, you can | ||
* {@link Event#setCanceled(boolean) cancel} it. | ||
* <p> | ||
* <b>Note:</b> Use {@link ItemTooltipEvent} to modify the text being displayed. | ||
* <p> | ||
* This event is fired on the {@link MinecraftForge#EVENT_BUS} (client-side only). | ||
* | ||
* @since 0.6.0 | ||
* @author glowredman | ||
* @see ItemTooltipEvent | ||
*/ | ||
@Cancelable | ||
public class RenderTooltipEvent extends Event { | ||
|
||
public static final int ORIGINAL_BG_START = 0xF0100010; | ||
public static final int ORIGINAL_BG_END = 0xF0100010; | ||
public static final int ORIGINAL_BORDER_START = 0x505000FF; | ||
public static final int ORIGINAL_BORDER_END = (ORIGINAL_BORDER_START & 0xFEFEFE) >> 1 | ||
| ORIGINAL_BORDER_START & 0xFF000000; | ||
|
||
/** | ||
* The ItemStack of which the tooltip is being displayed | ||
*/ | ||
@Nonnull | ||
public final ItemStack itemStack; | ||
|
||
/** | ||
* The GUI in which the tooltip is being rendered | ||
*/ | ||
@Nonnull | ||
public final GuiScreen gui; | ||
|
||
/** | ||
* The upper background color in ARGB format | ||
* <p> | ||
* Default value: {@code 0xF0100010} | ||
*/ | ||
public int backgroundStart; | ||
|
||
/** | ||
* The lower background color in ARGB format | ||
* <p> | ||
* Default value: {@code 0xF0100010} | ||
*/ | ||
public int backgroundEnd; | ||
|
||
/** | ||
* The upper border color in ARGB format | ||
* <p> | ||
* Default value: {@code 0x505000FF} | ||
*/ | ||
public int borderStart; | ||
|
||
/** | ||
* The lower border color in ARGB format | ||
* <p> | ||
* Default value: {@code 0x5028007F} | ||
*/ | ||
public int borderEnd; | ||
|
||
/** | ||
* The X coordinate of the mouse cursor | ||
*/ | ||
public int x; | ||
|
||
/** | ||
* The Y coordinate of the mouse cursor | ||
*/ | ||
public int y; | ||
|
||
/** | ||
* The FontRenderer used to render the tooltip's text | ||
* <p> | ||
* Default value: {@link GuiScreen#fontRendererObj} or {@link Item#getFontRenderer(ItemStack)} (if that method | ||
* doesn't return {@code null}) | ||
*/ | ||
@Nonnull | ||
public FontRenderer font; | ||
|
||
/** | ||
* Optional hook to completely replace the rendering code. Will be used instead of the vanilla code if not | ||
* {@code null}. The provided argument is the text to render. | ||
* <p> | ||
* <b>Note:</b> The usage may break compat with other mods, for example AppleCore! | ||
* <p> | ||
* Default value: {@code null} | ||
* | ||
* @apiNote The following GL states will be disabled before calling this hook: {@link GL12#GL_RESCALE_NORMAL}, | ||
* {@link GL11#GL_LIGHTING}, {@link GL11#GL_LIGHT0}, {@link GL11#GL_LIGHT1}, | ||
* {@link GL11#GL_COLOR_MATERIAL}, {@link GL11#GL_DEPTH_TEST}. They will be re-enabled after the hook is | ||
* called. {@link Gui#zLevel GuiScreen.zLevel} and {@link RenderItem#zLevel GuiScreen.itemRender.zLevel} | ||
* are set to {@code 300} before calling {@link Consumer#accept(Object) alternativeRenderer.accept(List)} | ||
* and reset to {@code 0} afterwards. Any more complex behaviors must be handled by the hook. An <a | ||
* href=https://forge.gemwire.uk/wiki/Access_Transformers>AccessTransformer</a> may be needed for this. | ||
*/ | ||
@Nullable | ||
public Consumer<List<String>> alternativeRenderer; | ||
|
||
public RenderTooltipEvent(ItemStack itemStack, GuiScreen gui, int backgroundStart, int backgroundEnd, | ||
int borderStart, int borderEnd, int x, int y, FontRenderer font) { | ||
this.itemStack = itemStack; | ||
this.gui = gui; | ||
this.backgroundStart = backgroundStart; | ||
this.backgroundEnd = backgroundEnd; | ||
this.borderStart = borderStart; | ||
this.borderEnd = borderEnd; | ||
this.x = x; | ||
this.y = y; | ||
this.font = font; | ||
} | ||
|
||
/** | ||
* Convenience method to set both background {@link #backgroundStart start}/{@link #backgroundEnd end} color to the | ||
* same value (the default background does not have a gradient) | ||
* | ||
* @param background The background color in ARGB format | ||
*/ | ||
public void setBackground(int background) { | ||
this.backgroundStart = background; | ||
this.backgroundEnd = background; | ||
} | ||
|
||
/** | ||
* Calculates {@link #borderEnd} based on {@link #borderStart} using the vanilla algorithm | ||
*/ | ||
public void calculateBorderEnd() { | ||
this.borderEnd = (this.borderStart & 0xFEFEFE) >> 1 | this.borderStart & 0xFF000000; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
187 changes: 187 additions & 0 deletions
187
src/main/java/com/gtnewhorizon/gtnhlib/mixins/early/MixinGuiScreen.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
package com.gtnewhorizon.gtnhlib.mixins.early; | ||
|
||
import static com.gtnewhorizon.gtnhlib.client.event.RenderTooltipEvent.*; | ||
|
||
import java.util.List; | ||
|
||
import net.minecraft.client.gui.FontRenderer; | ||
import net.minecraft.client.gui.Gui; | ||
import net.minecraft.client.gui.GuiScreen; | ||
import net.minecraft.client.renderer.RenderHelper; | ||
import net.minecraft.client.renderer.entity.RenderItem; | ||
import net.minecraft.item.ItemStack; | ||
import net.minecraftforge.common.MinecraftForge; | ||
|
||
import org.lwjgl.opengl.GL11; | ||
import org.lwjgl.opengl.GL12; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Overwrite; | ||
import org.spongepowered.asm.mixin.Shadow; | ||
import org.spongepowered.asm.mixin.Unique; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
|
||
import com.gtnewhorizon.gtnhlib.client.event.RenderTooltipEvent; | ||
|
||
// This mixin must run before AppleCore's GuiScreenMixin because we're using an @Overwrite | ||
@Mixin(priority = 999, value = GuiScreen.class) | ||
public class MixinGuiScreen extends Gui { | ||
|
||
@Unique | ||
private ItemStack gtnhlib$currentStack; | ||
|
||
@Shadow | ||
protected static RenderItem itemRender; | ||
@Shadow | ||
public int width; | ||
@Shadow | ||
public int height; | ||
|
||
@Inject(at = @At("HEAD"), method = "renderToolTip") | ||
private void preRenderToolTip(ItemStack itemIn, int x, int y, CallbackInfo ci) { | ||
this.gtnhlib$currentStack = itemIn; | ||
} | ||
|
||
@Inject(at = @At("TAIL"), method = "renderToolTip") | ||
private void postRenderToolTip(CallbackInfo ci) { | ||
this.gtnhlib$currentStack = null; | ||
} | ||
|
||
/** | ||
* @author glowredman | ||
* @reason Add RenderTooltipEvent | ||
*/ | ||
@Overwrite(remap = false) | ||
protected void drawHoveringText(List<String> textLines, int mouseX, int mouseY, FontRenderer font) { | ||
if (!textLines.isEmpty()) { | ||
// spotless:off | ||
/*************************************************************************************************************************************** | ||
* IMPORTANT NOTE: * | ||
* The int variables width, lineWidth, x, y and height must stay in this order and no other int variables may be inserted before them. * | ||
* This due to compat with AppleCore. * | ||
* * | ||
* The potentially conflicting mixin can be found here: * | ||
* https://github.com/GTNewHorizons/AppleCore/blob/master/src/main/java/squeek/applecore/mixins/early/minecraft/GuiScreenMixin.java * | ||
***************************************************************************************************************************************/ | ||
// spotless:on | ||
|
||
// create event | ||
RenderTooltipEvent event = new RenderTooltipEvent( | ||
this.gtnhlib$currentStack, | ||
(GuiScreen) (Object) this, | ||
ORIGINAL_BG_START, | ||
ORIGINAL_BG_END, | ||
ORIGINAL_BORDER_START, | ||
ORIGINAL_BORDER_END, | ||
mouseX, | ||
mouseY, | ||
font); | ||
|
||
// post event if called from renderToolTip | ||
if (this.gtnhlib$currentStack != null) { | ||
MinecraftForge.EVENT_BUS.post(event); | ||
if (event.isCanceled()) { | ||
// skip all rendering | ||
return; | ||
} | ||
} | ||
|
||
// set GL states | ||
GL11.glDisable(GL12.GL_RESCALE_NORMAL); | ||
RenderHelper.disableStandardItemLighting(); | ||
GL11.glDisable(GL11.GL_LIGHTING); | ||
GL11.glDisable(GL11.GL_DEPTH_TEST); | ||
|
||
if (event.alternativeRenderer == null) { | ||
// re-assign variables because they might have been modified by an event handler | ||
mouseX = event.x; | ||
mouseY = event.y; | ||
font = event.font; | ||
|
||
// determine max line width | ||
int width = 0; | ||
for (String s : textLines) { | ||
int lineWidth = font.getStringWidth(s); | ||
if (lineWidth > width) { | ||
width = lineWidth; | ||
} | ||
} | ||
|
||
// calculate coordinates | ||
int x = mouseX + 12; | ||
int y = mouseY - 12; | ||
int height = 8; | ||
|
||
if (textLines.size() > 1) { | ||
height += 2 + (textLines.size() - 1) * 10; | ||
} | ||
|
||
if (x + width > this.width) { | ||
x -= 28 + width; | ||
} | ||
|
||
if (y + height + 6 > this.height) { | ||
y = this.height - height - 6; | ||
} | ||
|
||
// set Z level | ||
this.zLevel = 300.0F; | ||
itemRender.zLevel = 300.0F; | ||
|
||
int backgroundStart = event.backgroundStart; | ||
int backgroundEnd = event.backgroundEnd; | ||
int borderStart = event.borderStart; | ||
int borderEnd = event.borderEnd; | ||
|
||
// spotless:off | ||
// draw background | ||
this.drawGradientRect(x - 3, y - 4, x + width + 3, y - 3, backgroundStart, backgroundStart); // top | ||
this.drawGradientRect(x - 3, y + height + 3, x + width + 3, y + height + 4, backgroundEnd, backgroundEnd); // bottom | ||
this.drawGradientRect(x - 3, y - 3, x + width + 3, y + height + 3, backgroundStart, backgroundEnd); // middle | ||
this.drawGradientRect(x - 4, y - 3, x - 3, y + height + 3, backgroundStart, backgroundEnd); // left | ||
this.drawGradientRect(x + width + 3, y - 3, x + width + 4, y + height + 3, backgroundStart, backgroundEnd); // right | ||
// draw inner border | ||
this.drawGradientRect(x - 3, y - 2, x - 2, y + height + 2, borderStart, borderEnd); // left | ||
this.drawGradientRect(x + width + 2, y - 2, x + width + 3, y + height + 2, borderStart, borderEnd); // right | ||
this.drawGradientRect(x - 3, y - 3, x + width + 3, y - 2, borderStart, borderStart); // top | ||
this.drawGradientRect(x - 3, y + height + 2, x + width + 3, y + height + 3, borderEnd, borderEnd); // bottom | ||
// spotless:on | ||
|
||
// draw text | ||
for (int i = 0; i < textLines.size(); i++) { | ||
String s = textLines.get(i); | ||
font.drawStringWithShadow(s, x, y, -1); | ||
|
||
// increase Y coordinate | ||
if (i == 0) { | ||
y += 2; | ||
} | ||
y += 10; | ||
} | ||
|
||
// reset Z level | ||
this.zLevel = 0.0F; | ||
itemRender.zLevel = 0.0F; | ||
} else { | ||
// set Z level | ||
this.zLevel = 300.0F; | ||
itemRender.zLevel = 300.0F; | ||
|
||
// render | ||
event.alternativeRenderer.accept(textLines); | ||
|
||
// reset Z level | ||
this.zLevel = 0.0F; | ||
itemRender.zLevel = 0.0F; | ||
} | ||
|
||
// reset GL states | ||
GL11.glEnable(GL11.GL_LIGHTING); | ||
GL11.glEnable(GL11.GL_DEPTH_TEST); | ||
RenderHelper.enableStandardItemLighting(); | ||
GL11.glEnable(GL12.GL_RESCALE_NORMAL); | ||
} | ||
} | ||
|
||
} |