Skip to content

Tooltip & Hover Fix #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions src/main/java/com/cleanroommc/modularui/api/widget/ITooltip.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.cleanroommc.modularui.api.drawable.IKey;
import com.cleanroommc.modularui.screen.Tooltip;
import com.cleanroommc.modularui.utils.Alignment;
import com.cleanroommc.modularui.widget.sizer.Area;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -69,17 +68,6 @@ default W tooltipBuilder(Consumer<Tooltip> tooltipBuilder) {
return getThis();
}

/**
* Sets an excluded area. The tooltip will always try to avoid the excluded area.
*
* @param area area to exclude
* @return this
*/
default W excludeTooltipArea(Area area) {
tooltip().excludeArea(area);
return getThis();
}

/**
* Sets a general tooltip position. The true position is calculated every frame.
*
Expand Down
82 changes: 40 additions & 42 deletions src/main/java/com/cleanroommc/modularui/screen/Tooltip.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.cleanroommc.modularui.api.drawable.IDrawable;
import com.cleanroommc.modularui.api.drawable.IIcon;
import com.cleanroommc.modularui.api.drawable.IKey;
import com.cleanroommc.modularui.api.widget.IWidget;
import com.cleanroommc.modularui.drawable.*;
import com.cleanroommc.modularui.screen.viewport.GuiContext;
import com.cleanroommc.modularui.utils.Alignment;
Expand All @@ -27,9 +28,9 @@

public class Tooltip {

private final IWidget parent;
private final List<IDrawable> lines = new ArrayList<>();
private List<IDrawable> additionalLines = new ArrayList<>();
private Area excludeArea;
private Pos pos = ModularUIConfig.tooltipPos;
private boolean customPos = false;
private Consumer<Tooltip> tooltipBuilder;
Expand All @@ -47,6 +48,10 @@ public class Tooltip {

private boolean dirty = true;

public Tooltip(IWidget parent) {
this.parent = parent;
}

public void buildTooltip() {
this.dirty = false;
this.lines.clear();
Expand Down Expand Up @@ -136,24 +141,24 @@ public Rectangle determineTooltipArea(GuiContext context, List<IDrawable> lines,
}

if (this.pos == Pos.NEXT_TO_MOUSE) {
final int PADDING = 8;
final int padding = 8;
// magic number to place tooltip nicer. Look at GuiScreen#L237
final int MOUSE_OFFSET = 12;
int x = mouseX + MOUSE_OFFSET, y = mouseY - MOUSE_OFFSET;
if (x < PADDING) {
x = PADDING;
} else if (x + width + PADDING > screenWidth) {
x -= MOUSE_OFFSET * 2 + width; // flip side of cursor
if (x < PADDING) {
x = PADDING;
final int mouseOffset = 12;
int x = mouseX + mouseOffset, y = mouseY - mouseOffset;
if (x < padding) {
x = padding;
} else if (x + width + padding > screenWidth) {
x -= mouseOffset * 2 + width; // flip side of cursor
if (x < padding) {
x = padding;
}
}
y = MathHelper.clamp(y, PADDING, screenHeight - PADDING - height);
y = MathHelper.clamp(y, padding, screenHeight - padding - height);
return new Rectangle(x, y, width, height);
}

if (this.excludeArea == null) {
throw new IllegalStateException();
if (this.parent == null) {
throw new IllegalStateException("Tooltip pos is " + this.pos.name() + ", but no widget parent is set!");
}

int minWidth = 0;
Expand All @@ -168,13 +173,16 @@ public Rectangle determineTooltipArea(GuiContext context, List<IDrawable> lines,
int shiftAmount = 10;
int padding = 7;

Area area = Area.SHARED;
area.set(this.parent.getArea());
area.setPos(0, 0); // context is transformed to this widget
area.transformAndRectanglerize(context);
int x = 0, y = 0;
if (this.pos.vertical) {
int xArea = this.excludeArea.x;
if (width < this.excludeArea.width) {
x = xArea + shiftAmount;
if (width < area.width) {
x = area.x + shiftAmount;
} else {
x = xArea - shiftAmount;
x = area.x - shiftAmount;
if (x < padding) {
x = padding;
} else if (x + width > screenWidth - padding) {
Expand All @@ -188,33 +196,32 @@ public Rectangle determineTooltipArea(GuiContext context, List<IDrawable> lines,

Pos pos = this.pos;
if (this.pos == Pos.VERTICAL) {
int bottomSpace = screenHeight - this.excludeArea.ey();
pos = bottomSpace < height + padding && bottomSpace < this.excludeArea.y ? Pos.ABOVE : Pos.BELOW;
int bottomSpace = screenHeight - area.ey();
pos = bottomSpace < height + padding && bottomSpace < area.y ? Pos.ABOVE : Pos.BELOW;
}

if (pos == Pos.BELOW) {
y = this.excludeArea.y + this.excludeArea.height + padding;
y = area.ey() + padding;
} else if (pos == Pos.ABOVE) {
y = this.excludeArea.y - height - padding;
y = area.y - height - padding;
}
} else if (this.pos.horizontal) {
boolean usedMoreSpaceSide = false;
Pos pos = this.pos;
if (this.pos == Pos.HORIZONTAL) {
if (this.excludeArea.x > screenWidth - this.excludeArea.x - this.excludeArea.width) {
if (area.x > screenWidth - area.ex()) {
pos = Pos.LEFT;
x = 0;
} else {
pos = Pos.RIGHT;
x = screenWidth - this.excludeArea.x - this.excludeArea.width + padding;
x = screenWidth - area.ex() + padding;
}
}

int yArea = this.excludeArea.y;
if (height < this.excludeArea.height) {
y = yArea + shiftAmount;
if (height < area.height) {
y = area.y + shiftAmount;
} else {
y = yArea - shiftAmount;
y = area.y - shiftAmount;
if (y < padding) {
y = padding;
}
Expand All @@ -223,9 +230,9 @@ public Rectangle determineTooltipArea(GuiContext context, List<IDrawable> lines,
if (x + width > screenWidth - padding) {
int maxWidth;
if (pos == Pos.LEFT) {
maxWidth = Math.max(minWidth, this.excludeArea.x - padding * 2);
maxWidth = Math.max(minWidth, area.x - padding * 2);
} else {
maxWidth = Math.max(minWidth, screenWidth - this.excludeArea.x - this.excludeArea.width - padding * 2);
maxWidth = Math.max(minWidth, screenWidth - area.ex() - padding * 2);
}
usedMoreSpaceSide = true;
renderer.setAlignment(this.alignment, maxWidth);
Expand All @@ -235,14 +242,14 @@ public Rectangle determineTooltipArea(GuiContext context, List<IDrawable> lines,
}

if (this.pos == Pos.HORIZONTAL && !usedMoreSpaceSide) {
int rightSpace = screenWidth - this.excludeArea.x - this.excludeArea.width;
pos = rightSpace < width + padding && rightSpace < this.excludeArea.x ? Pos.LEFT : Pos.RIGHT;
int rightSpace = screenWidth - area.ex();
pos = rightSpace < width + padding && rightSpace < area.x ? Pos.LEFT : Pos.RIGHT;
}

if (pos == Pos.RIGHT) {
x = this.excludeArea.x + this.excludeArea.width + padding;
x = area.ex() + padding;
} else if (pos == Pos.LEFT) {
x = this.excludeArea.x - width - padding;
x = area.x - width - padding;
}
}
return new Rectangle(x, y, width, height);
Expand All @@ -259,10 +266,6 @@ public void markDirty() {
this.dirty = true;
}

public Area getExcludeArea() {
return this.excludeArea;
}

public int getShowUpTimer() {
return this.showUpTimer;
}
Expand All @@ -280,11 +283,6 @@ public boolean hasTitleMargin() {
return this.hasTitleMargin;
}

public Tooltip excludeArea(Area area) {
this.excludeArea = area;
return this;
}

public Tooltip pos(Pos pos) {
this.customPos = true;
this.pos = pos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,7 @@ public void rotate(float angle, float x, float y, float z) {
}

public void rotateZ(float angle) {
checkViewport();
this.top.getMatrix().rotate(angle, vec(0f, 0f, 1f));
this.top.markDirty();
rotate(angle, 0f, 0f, 1f);
}

public void scale(float x, float y) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static void onItemUse(PlayerInteractEvent.RightClickItem event) {
.inFrontOf(Minecraft.getMinecraft().player, 5, false)
.screenScale(0.5f)
.open(new TestGui());*/
ClientGUI.open(new TestGui());
ClientGUI.open(new ResizerTest());
}
}
}
31 changes: 25 additions & 6 deletions src/main/java/com/cleanroommc/modularui/test/ResizerTest.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.cleanroommc.modularui.test;

import com.cleanroommc.modularui.api.drawable.IKey;
import com.cleanroommc.modularui.api.layout.IViewportStack;
import com.cleanroommc.modularui.drawable.GuiTextures;
import com.cleanroommc.modularui.screen.CustomModularScreen;
import com.cleanroommc.modularui.screen.ModularPanel;
import com.cleanroommc.modularui.screen.viewport.GuiContext;
import com.cleanroommc.modularui.utils.Alignment;
import com.cleanroommc.modularui.widgets.ButtonWidget;
import com.cleanroommc.modularui.widgets.layout.Column;
import com.cleanroommc.modularui.widgets.layout.Row;
import com.cleanroommc.modularui.widget.Widget;

import net.minecraft.client.Minecraft;

import org.jetbrains.annotations.NotNull;

Expand All @@ -25,14 +26,32 @@ public class ResizerTest extends CustomModularScreen {
.align(Alignment.Center));*/
return ModularPanel.defaultPanel("main")
.size(150)
.child(new Column()
.child(new SpinningWidget()
.size(80, 20)
.center()
.background(GuiTextures.MC_BUTTON)
.overlay(IKey.str("Text"))
.addTooltipLine("Long Tooltip Line"));
/*.child(new Column()
.alignX(0.5f)
.heightRel(1f)
.margin(0, 7)
.coverChildrenWidth()
.mainAxisAlignment(Alignment.MainAxis.SPACE_BETWEEN)
.child(new ButtonWidget<>().width(40))
.child(new Row().height(30).widthRel(1f).background(GuiTextures.CHECKBOARD).debugName("row"))
.child(new ButtonWidget<>()));
.child(new ButtonWidget<>()));*/
}

private static class SpinningWidget extends Widget<SpinningWidget> {

@Override
public void transform(IViewportStack stack) {
super.transform(stack);
stack.translate(getArea().width / 2f, getArea().height / 2f);
float p = Minecraft.getSystemTime() % 4000 / 4000f;
stack.rotateZ((float) (p * Math.PI * 2));
stack.translate(-getArea().width / 2f, -getArea().height / 2f);
}
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/cleanroommc/modularui/test/TestGui.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public void onClose() {
List<List<AvailableElement>> availableMatrix = Grid.mapToMatrix(2, this.lines, (index, value) -> {
AvailableElement availableElement = new AvailableElement().overlay(IKey.str(value))
.size(60, 14)
.addTooltipLine(value)
.onMousePressed(mouseButton1 -> {
if (this.availableElements.get(value).available) {
ref.get().add(value, -1);
Expand Down Expand Up @@ -85,6 +86,7 @@ public void onClose() {
.pos(10, 10).right(10).bottom(10))*/
SortableListWidget<String, SortableListWidget.Item<String>> sortableListWidget = SortableListWidget.sortableBuilder(this.lines, this.configuredOptions,
s -> new SortableListWidget.Item<>(s, new Widget<>()
.addTooltipLine(s)
.background(GuiTextures.BUTTON_CLEAN)
.overlay(IKey.str(s))
.left(0).right(10))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.cleanroommc.modularui.api.widget.IWidget;
import com.cleanroommc.modularui.screen.ModularPanel;

import com.cleanroommc.modularui.theme.WidgetTheme;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
Expand All @@ -25,7 +27,13 @@ public boolean canHover() {
return getBackground() != null ||
getHoverBackground() != null ||
getHoverOverlay() != null ||
getTooltip() != null;
getTooltip() != null ||
hasThemeBackground();
}

protected boolean hasThemeBackground() {
WidgetTheme widgetTheme = getWidgetTheme(getContext().getTheme());
return widgetTheme.getBackground() != null || widgetTheme.getHoverBackground() != null;
}

public boolean addChild(IWidget child, int index) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/cleanroommc/modularui/widget/Widget.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public Tooltip getTooltip() {
@Override
public @NotNull Tooltip tooltip() {
if (this.tooltip == null) {
this.tooltip = new Tooltip().excludeArea(getArea());
this.tooltip = new Tooltip(this);
}
return this.tooltip;
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/cleanroommc/modularui/widget/WidgetTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,24 @@ public static void drawTree(IWidget parent, GuiContext context, boolean ignoreEn
}

public static void drawTreeForeground(IWidget parent, GuiContext context) {
IViewport viewport = parent instanceof IViewport viewport1 ? viewport1 : null;
context.pushMatrix();
parent.transform(context);

GlStateManager.color(1, 1, 1, 1);
GlStateManager.enableBlend();
parent.drawForeground(context);

List<IWidget> children = parent.getChildren();
if (!children.isEmpty()) {
if (viewport != null) {
context.pushViewport(viewport, parent.getArea());
viewport.transformChildren(context);
}
children.forEach(widget -> drawTreeForeground(widget, context));
if (viewport != null) context.popViewport(viewport);
}
context.popMatrix();
}

@ApiStatus.Internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ public CycleButtonWidget addTooltip(int state, String tooltip) {

public CycleButtonWidget length(int length) {
this.length = length;
// adjust tooltip buffer size
while (this.stateTooltip.size() < this.length) {
Tooltip tooltip = new Tooltip().excludeArea(getArea());
this.stateTooltip.add(tooltip);
this.stateTooltip.add(new Tooltip(this));
}
while (this.stateTooltip.size() > this.length) {
this.stateTooltip.remove(this.stateTooltip.size() - 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public class ItemSlot extends Widget<ItemSlot> implements IVanillaSlot, Interact
public ItemSlot() {
tooltip().setAutoUpdate(true).setHasTitleMargin(true);
tooltipBuilder(tooltip -> {
tooltip.excludeArea(getArea());
if (!isSynced()) return;
ItemStack stack = getSlot().getStack();
if (stack.isEmpty()) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ public class ScrollingTextWidget extends TextWidget {
public ScrollingTextWidget(IKey key) {
super(key);
tooltipBuilder(tooltip -> {
tooltip.excludeArea(getArea())
.showUpTimer(10);
tooltip.showUpTimer(10);
if (this.line.getWidth() > getArea().width) {
tooltip.addLine(key);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ public void onInit() {
}
setText(this.stringValue.getStringValue());
if (!hasTooltip()) {
tooltip().excludeArea(getArea());
tooltipBuilder(tooltip -> tooltip.addLine(IKey.str(getText())));
}
if (!this.changedMarkedColor) {
Expand Down