Add tooltips to gui elements
This commit is contained in:
@@ -37,6 +37,14 @@ public interface GuiRenderer {
|
||||
|
||||
void drawTexturedRect(int x, int y, int u, int v, int width, int height);
|
||||
|
||||
void drawRect(int x, int y, int width, int height, int color);
|
||||
|
||||
void drawRect(int x, int y, int width, int height, ReadableColor color);
|
||||
|
||||
void drawRect(int x, int y, int width, int height, int topLeftColor, int topRightColor, int bottomLeftColor, int bottomRightColor);
|
||||
|
||||
void drawRect(int x, int y, int width, int height, ReadableColor topLeftColor, ReadableColor topRightColor, ReadableColor bottomLeftColor, ReadableColor bottomRightColor);
|
||||
|
||||
int drawString(int x, int y, int color, String text);
|
||||
|
||||
int drawString(int x, int y, ReadableColor color, String text);
|
||||
|
||||
@@ -26,9 +26,15 @@ import lombok.NonNull;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.util.Color;
|
||||
import org.lwjgl.util.*;
|
||||
|
||||
import static net.minecraft.client.renderer.GlStateManager.*;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
public class MinecraftGuiRenderer implements GuiRenderer {
|
||||
|
||||
private final Gui gui = new Gui();
|
||||
@@ -60,6 +66,46 @@ public class MinecraftGuiRenderer implements GuiRenderer {
|
||||
gui.drawTexturedModalRect(x, y, u, v, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(int x, int y, int width, int height, int color) {
|
||||
Gui.drawRect(x, y, x + width, y + height, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(int x, int y, int width, int height, ReadableColor color) {
|
||||
drawRect(x, y, width, height, color(color));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(int x, int y, int width, int height, int topLeftColor, int topRightColor, int bottomLeftColor, int bottomRightColor) {
|
||||
drawRect(x, y, width, height, color(topLeftColor), color(topRightColor), color(bottomLeftColor), color(bottomRightColor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(int x, int y, int width, int height, ReadableColor tl, ReadableColor tr, ReadableColor bl, ReadableColor br) {
|
||||
disableTexture2D();
|
||||
enableBlend();
|
||||
disableAlpha();
|
||||
tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 1, 0);
|
||||
shadeModel(GL_SMOOTH);
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
WorldRenderer renderer = tessellator.getWorldRenderer();
|
||||
renderer.startDrawingQuads();
|
||||
renderer.setColorRGBA(bl.getRed(), bl.getGreen(), bl.getBlue(), bl.getAlpha());
|
||||
renderer.addVertex(x, y + height, 0);
|
||||
renderer.setColorRGBA(br.getRed(), br.getGreen(), br.getBlue(), br.getAlpha());
|
||||
renderer.addVertex(x + width, y + height, 0);
|
||||
renderer.setColorRGBA(tr.getRed(), tr.getGreen(), tr.getBlue(), tr.getAlpha());
|
||||
renderer.addVertex(x + width, y, 0);
|
||||
renderer.setColorRGBA(tl.getRed(), tl.getGreen(), tl.getBlue(), tl.getAlpha());
|
||||
renderer.addVertex(x, y, 0);
|
||||
tessellator.draw();
|
||||
shadeModel(GL_FLAT);
|
||||
disableBlend();
|
||||
enableAlpha();
|
||||
enableTexture2D();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int drawString(int x, int y, int color, String text) {
|
||||
FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
|
||||
@@ -88,4 +134,8 @@ public class MinecraftGuiRenderer implements GuiRenderer {
|
||||
| color.getGreen() << 8
|
||||
| color.getBlue();
|
||||
}
|
||||
|
||||
private ReadableColor color(int color) {
|
||||
return new Color((color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, (color >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,26 @@ public class OffsetGuiRenderer implements GuiRenderer {
|
||||
renderer.drawTexturedRect(x + position.getX(), y + position.getY(), u, v, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(int x, int y, int width, int height, int color) {
|
||||
renderer.drawRect(x + position.getX(), y + position.getY(), width, height, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(int x, int y, int width, int height, ReadableColor color) {
|
||||
renderer.drawRect(x + position.getX(), y + position.getY(), width, height, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(int x, int y, int width, int height, int topLeftColor, int topRightColor, int bottomLeftColor, int bottomRightColor) {
|
||||
renderer.drawRect(x + position.getX(), y + position.getY(), width, height, topLeftColor, topRightColor, bottomLeftColor, bottomRightColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(int x, int y, int width, int height, ReadableColor topLeftColor, ReadableColor topRightColor, ReadableColor bottomLeftColor, ReadableColor bottomRightColor) {
|
||||
renderer.drawRect(x + position.getX(), y + position.getY(), width, height, topLeftColor, topRightColor, bottomLeftColor, bottomRightColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int drawString(int x, int y, int color, String text) {
|
||||
return renderer.drawString(x + position.getX(), y + position.getY(), color, text) - position.getX();
|
||||
|
||||
@@ -26,17 +26,23 @@ import de.johni0702.minecraft.gui.GuiRenderer;
|
||||
import de.johni0702.minecraft.gui.MinecraftGuiRenderer;
|
||||
import de.johni0702.minecraft.gui.OffsetGuiRenderer;
|
||||
import de.johni0702.minecraft.gui.RenderInfo;
|
||||
import de.johni0702.minecraft.gui.element.GuiElement;
|
||||
import de.johni0702.minecraft.gui.element.GuiLabel;
|
||||
import de.johni0702.minecraft.gui.function.*;
|
||||
import eu.crushedpixel.replaymod.utils.MouseUtils;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
import net.minecraft.util.ReportedException;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.util.Dimension;
|
||||
import org.lwjgl.util.Point;
|
||||
import org.lwjgl.util.ReadableDimension;
|
||||
import org.lwjgl.util.ReadablePoint;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public abstract class AbstractGuiScreen<T extends AbstractGuiScreen<T>> extends AbstractGuiContainer<T> {
|
||||
|
||||
@@ -70,6 +76,59 @@ public abstract class AbstractGuiScreen<T extends AbstractGuiScreen<T>> extends
|
||||
title.draw(eRenderer, null, null);
|
||||
}
|
||||
super.draw(renderer, size, renderInfo);
|
||||
|
||||
final GuiElement tooltip = forEach(GuiElement.class).getTooltip(renderInfo);
|
||||
if (tooltip != null) {
|
||||
final ReadableDimension tooltipSize = tooltip.getMinSize();
|
||||
int dx, dy;
|
||||
if (renderInfo.mouseX + 8 + tooltipSize.getWidth() < screenSize.getWidth()) {
|
||||
dx = 8;
|
||||
} else {
|
||||
dx = -8;
|
||||
}
|
||||
if (renderInfo.mouseY + 8 + tooltipSize.getHeight() < screenSize.getHeight()) {
|
||||
dy = 8;
|
||||
} else {
|
||||
dy = -8;
|
||||
}
|
||||
final ReadablePoint position = new Point(renderInfo.mouseX + dx, renderInfo.mouseY + dy);
|
||||
try {
|
||||
OffsetGuiRenderer eRenderer = new OffsetGuiRenderer(renderer, position, tooltipSize);
|
||||
tooltip.draw(eRenderer, tooltipSize, renderInfo.offsetMouse(position.getX(), position.getY()));
|
||||
} catch (Exception ex) {
|
||||
CrashReport crashReport = CrashReport.makeCrashReport(ex, "Rendering Gui Tooltip");
|
||||
renderInfo.addTo(crashReport);
|
||||
CrashReportCategory category = crashReport.makeCategory("Gui container details");
|
||||
category.addCrashSectionCallable("Container", new Callable() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
return this;
|
||||
}
|
||||
});
|
||||
category.addCrashSection("Width", size.getWidth());
|
||||
category.addCrashSection("Height", size.getHeight());
|
||||
category = crashReport.makeCategory("Tooltip details");
|
||||
category.addCrashSectionCallable("Element", new Callable() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
return tooltip;
|
||||
}
|
||||
});
|
||||
category.addCrashSectionCallable("Position", new Callable() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
return position;
|
||||
}
|
||||
});
|
||||
category.addCrashSectionCallable("Size", new Callable() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
return tooltipSize;
|
||||
}
|
||||
});
|
||||
throw new ReportedException(crashReport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -47,6 +47,7 @@ public abstract class AbstractComposedGuiElement<T extends AbstractComposedGuiEl
|
||||
return (C) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{ofType}, new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
boolean isGetter = method.getName().startsWith("get");
|
||||
Object handled = null;
|
||||
for (final GuiElement element : getChildren()) {
|
||||
try {
|
||||
@@ -55,8 +56,14 @@ public abstract class AbstractComposedGuiElement<T extends AbstractComposedGuiEl
|
||||
} else if (ofType.isInstance(element)) {
|
||||
handled = method.invoke(element, args);
|
||||
}
|
||||
if (Boolean.TRUE.equals(handled)) {
|
||||
break;
|
||||
if (handled != null) {
|
||||
if (handled instanceof Boolean) {
|
||||
if (Boolean.TRUE.equals(handled)) {
|
||||
break;
|
||||
}
|
||||
} else if (isGetter) {
|
||||
return handled;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CrashReport crash = CrashReport.makeCrashReport(e, "Calling Gui method");
|
||||
|
||||
@@ -22,10 +22,12 @@
|
||||
|
||||
package de.johni0702.minecraft.gui.element;
|
||||
|
||||
import de.johni0702.minecraft.gui.RenderInfo;
|
||||
import de.johni0702.minecraft.gui.container.GuiContainer;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.lwjgl.util.Dimension;
|
||||
import org.lwjgl.util.Point;
|
||||
import org.lwjgl.util.ReadableDimension;
|
||||
|
||||
public abstract class AbstractGuiElement<T extends AbstractGuiElement<T>> implements GuiElement<T> {
|
||||
@@ -35,6 +37,8 @@ public abstract class AbstractGuiElement<T extends AbstractGuiElement<T>> implem
|
||||
@Getter
|
||||
private GuiContainer container;
|
||||
|
||||
private GuiElement tooltip;
|
||||
|
||||
@Getter
|
||||
private boolean enabled = true;
|
||||
|
||||
@@ -65,6 +69,30 @@ public abstract class AbstractGuiElement<T extends AbstractGuiElement<T>> implem
|
||||
return setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuiElement getTooltip(RenderInfo renderInfo) {
|
||||
if (tooltip != null) {
|
||||
Point mouse = new Point(renderInfo.mouseX, renderInfo.mouseY);
|
||||
if (container != null) {
|
||||
container.convertFor(this, mouse);
|
||||
}
|
||||
ReadableDimension size = getMinSize();
|
||||
if (mouse.getX() > 0
|
||||
&& mouse.getY() > 0
|
||||
&& mouse.getX() < size.getWidth()
|
||||
&& mouse.getY() < size.getHeight()) {
|
||||
return tooltip;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setTooltip(GuiElement tooltip) {
|
||||
this.tooltip = tooltip;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setContainer(GuiContainer container) {
|
||||
this.container = container;
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2015 johni0702
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package de.johni0702.minecraft.gui.element;
|
||||
|
||||
import de.johni0702.minecraft.gui.GuiRenderer;
|
||||
import de.johni0702.minecraft.gui.RenderInfo;
|
||||
import eu.crushedpixel.replaymod.utils.StringUtils;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import org.lwjgl.util.Color;
|
||||
import org.lwjgl.util.Dimension;
|
||||
import org.lwjgl.util.ReadableColor;
|
||||
import org.lwjgl.util.ReadableDimension;
|
||||
|
||||
public abstract class AbstractGuiTooltip<T extends AbstractGuiTooltip<T>> extends AbstractGuiElement<T> {
|
||||
private static final int LINE_SPACING = 3;
|
||||
private static final ReadableColor BACKGROUND_COLOR = new Color(16, 0, 16, 240);
|
||||
private static final ReadableColor BORDER_LIGHT = new Color(80, 0, 255, 80);
|
||||
private static final ReadableColor BORDER_DARK = new Color(40, 0, 127, 80);
|
||||
|
||||
@Getter
|
||||
private String[] text = {};
|
||||
|
||||
@Getter
|
||||
private ReadableColor color = ReadableColor.WHITE;
|
||||
|
||||
@Override
|
||||
public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) {
|
||||
int width = size.getWidth();
|
||||
int height = size.getHeight();
|
||||
|
||||
// Draw background
|
||||
renderer.drawRect(1, 0, width - 2, height, BACKGROUND_COLOR); // Top to bottom
|
||||
renderer.drawRect(0, 1, 1, height - 2, BACKGROUND_COLOR); // Left pixel row
|
||||
renderer.drawRect(width - 1, 1, 1, height - 2, BACKGROUND_COLOR); // Right pixel row
|
||||
|
||||
// Draw the border, it gets darker from top to bottom
|
||||
renderer.drawRect(1, 1, width - 2, 1, BORDER_LIGHT); // Top border
|
||||
renderer.drawRect(1, height - 2, width - 2, 1, BORDER_DARK); // Bottom border
|
||||
renderer.drawRect(1, 2, 1, height - 4, BORDER_LIGHT, BORDER_LIGHT, BORDER_DARK, BORDER_DARK); // Left border
|
||||
renderer.drawRect(width - 2, 2, 1, height - 4, BORDER_LIGHT, BORDER_LIGHT, BORDER_DARK, BORDER_DARK); // Right border
|
||||
|
||||
FontRenderer fontRenderer = getMinecraft().fontRendererObj;
|
||||
int y = LINE_SPACING + 1;
|
||||
for (String line : text) {
|
||||
renderer.drawString(LINE_SPACING + 1, y, color, line);
|
||||
y += fontRenderer.FONT_HEIGHT + LINE_SPACING;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadableDimension getMinSize() {
|
||||
FontRenderer fontRenderer = getMinecraft().fontRendererObj;
|
||||
int height = 1 + LINE_SPACING + text.length * (fontRenderer.FONT_HEIGHT + LINE_SPACING);
|
||||
int width = 0;
|
||||
for (String line : text) {
|
||||
int w = fontRenderer.getStringWidth(line);
|
||||
if (w > width) {
|
||||
width = w;
|
||||
}
|
||||
}
|
||||
width+=4 * 2;
|
||||
return new Dimension(width, height);
|
||||
}
|
||||
|
||||
public T setText(String[]text) {
|
||||
this.text = text;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public T setText(String text) {
|
||||
return setText(StringUtils.splitStringInMultipleRows(text, 250));
|
||||
}
|
||||
|
||||
public T setI18nText(String text, Object... args) {
|
||||
return setText(I18n.format(text, args));
|
||||
}
|
||||
|
||||
public T setColor(ReadableColor color) {
|
||||
this.color = color;
|
||||
return getThis();
|
||||
}
|
||||
}
|
||||
@@ -49,4 +49,7 @@ public interface GuiElement<T extends GuiElement<T>> {
|
||||
T setEnabled();
|
||||
T setDisabled();
|
||||
|
||||
GuiElement getTooltip(RenderInfo renderInfo);
|
||||
T setTooltip(GuiElement tooltip);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2015 johni0702
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package de.johni0702.minecraft.gui.element;
|
||||
|
||||
public class GuiTooltip extends AbstractGuiTooltip<GuiTooltip> {
|
||||
@Override
|
||||
protected GuiTooltip getThis() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user