Merge pull request #8008 from Eradev/7859-DisplayTextTooltip

Allow the display of the placeholder in shops and reward windows.
This commit is contained in:
kevlahnota
2025-07-26 06:57:27 +08:00
committed by GitHub
3 changed files with 146 additions and 86 deletions

View File

@@ -69,7 +69,6 @@ public class RewardScene extends UIScene {
private int remainingSelections = 0;
private RewardScene() {
super(Forge.isLandscapeMode() ? "ui/items.json" : "ui/items_portrait.json");
playerGold = Controls.newAccountingLabel(ui.findActor("playerGold"), false);
@@ -103,7 +102,6 @@ public class RewardScene extends UIScene {
}
private void toggleToolTip() {
Selectable selectable = getSelected();
if (selectable == null)
return;
@@ -165,7 +163,6 @@ public class RewardScene extends UIScene {
if (type != null) {
switch (type) {
case Shop:
break;
case QuestReward:
case Loot:
break;
@@ -186,7 +183,7 @@ public class RewardScene extends UIScene {
if (type == Type.Loot)
AdventurePlayer.current().addReward(reward.getReward());
if (type == Type.QuestReward)
AdventurePlayer.current().addReward(reward.getReward()); // Want to customize this soon to have selectable rewards which will be handled different here
AdventurePlayer.current().addReward(reward.getReward()); // TODO Want to customize this soon to have selectable rewards which will be handled different here
reward.clearHoldToolTip();
try {
stage.getActors().removeValue(reward, true);
@@ -470,7 +467,9 @@ public class RewardScene extends UIScene {
mul *= 0.8f;
}
cardHeight = bestCardHeight * 0.90f;
Float custom = Forge.isLandscapeMode() ? Config.instance().getSettingData().rewardCardAdjLandscape : Config.instance().getSettingData().rewardCardAdj;
Float custom = Forge.isLandscapeMode()
? Config.instance().getSettingData().rewardCardAdjLandscape
: Config.instance().getSettingData().rewardCardAdj;
if (custom != null && custom != 1f) {
mul *= custom;
} else {
@@ -484,7 +483,6 @@ public class RewardScene extends UIScene {
mul *= Forge.isLandscapeMode() ? 1.05f : 1.5f;
else if (fW / fH >= 2f)
mul *= Forge.isLandscapeMode() ? 1f : 1.4f;
}
}
cardWidth = (cardHeight / CARD_WIDTH_TO_HEIGHT) * mul;
@@ -502,7 +500,6 @@ public class RewardScene extends UIScene {
}
}
int currentRow = (i / numberOfColumns);
float lastRowXAdjust = 0;
if (currentRow == numberOfRows - 1) {
@@ -547,7 +544,6 @@ public class RewardScene extends UIScene {
}
}
private void updateBuyButtons() {
for (Actor actor : new Array.ArrayIterator<>(generated)) {
if (actor instanceof BuyButton) {
@@ -636,7 +632,6 @@ public class RewardScene extends UIScene {
private final int index;
public RewardActor rewardActor;
private Reward reward;
int price;
boolean isSold;
void update() {
@@ -656,7 +651,6 @@ public class RewardScene extends UIScene {
setText("Pick Reward" + "\n" + Forge.getLocalizer().getMessage("lblOwned") + ": " + AdventurePlayer.current().countItem(reward.getItem().name));
}
public ChooseRewardButton(int i, RewardActor actor, Reward reward, TextraButton style) {
super("", style.getStyle(), Controls.getTextraFont());
this.index = i;

View File

@@ -21,6 +21,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Tooltip;
import com.badlogic.gdx.scenes.scene2d.ui.TooltipManager;
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.DragListener;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Disposable;
@@ -73,7 +74,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
final int preview_h = 680;
TextureRegion backTexture;
Texture image, T, Talt;
Texture image, T, Tnotext, Talt, Taltnotext;
Graphics graphics;
Texture generatedTooltip = null; //Storage for a generated tooltip. To dispose of on exit.
boolean needsToBeDisposed;
@@ -91,7 +92,10 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
public int renderedCount = 0; //Counter for cards that require rendering a preview.
static final ImageFetcher fetcher = GuiBase.getInterface().getImageFetcher();
RewardImage toolTipImage;
RewardImage alternateToolTipImage;
String description = "";
private boolean shouldDisplayText = false;
private boolean isDragging = false;
@Override
public void dispose() {
@@ -127,7 +131,6 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
PaperCard card = ImageUtil.getPaperCardFromImageKey(imageKey);
imageKey = card.getCardImageKey();
int count = 0;
if (StringUtils.isBlank(imageKey))
return;
@@ -177,10 +180,6 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
tooltip.setActor(new ComplexTooltip(toolTipImage));
}
}
if (T != null)
T.dispose();
if (alternate && Talt != null)
Talt.dispose();
ImageCache.getInstance().updateSynqCount(imageFile, count);
if (Forge.getCurrentScene() instanceof RewardScene)
RewardScene.instance().reactivateInputs();
@@ -230,6 +229,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
this.isRewardShop = RewardScene.Type.Shop.equals(type);
this.isLoot = RewardScene.Type.Loot.equals(type);
this.showOverlay = showOverlay;
if (backTexture == null) {
backTexture = FSkin.getSleeves().get(0);
}
@@ -257,6 +257,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
});
}
hasbackface = reward.getCard().hasBackFace();
if (ImageCache.getInstance().imageKeyFileExists(reward.getCard().getImageKey(false)) && !Forge.enableUIMask.equals("Art")) {
int count = 0;
PaperCard card = ImageUtil.getPaperCardFromImageKey(reward.getCard().getImageKey(false));
@@ -283,33 +284,6 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
loaded = false;
}
ImageCache.getInstance().updateSynqCount(frontFace, count);
//preload card back for performance
if (hasbackface) {
if (ImageCache.getInstance().imageKeyFileExists(reward.getCard().getImageKey(true))) {
PaperCard cardBack = ImageUtil.getPaperCardFromImageKey(reward.getCard().getImageKey(true));
File backFace = ImageKeys.getImageFile(cardBack.getCardAltImageKey());
if (backFace != null) {
try {
Texture back = Forge.getAssets().manager().get(backFace.getPath(), Texture.class, false);
if (back == null) {
Forge.getAssets().manager().load(backFace.getPath(), Texture.class, Forge.getAssets().getTextureFilter());
Forge.getAssets().manager().finishLoadingAsset(backFace.getPath());
back = Forge.getAssets().manager().get(backFace.getPath(), Texture.class, false);
}
if (back != null) {
ImageCache.getInstance().updateSynqCount(backFace, 1);
generateBackFace(reward, back);
} else {
generateBackFace(reward, getRenderedBackface(reward));
}
} catch (Exception e) {
System.err.println("Failed to load image: " + backFace.getPath());
}
}
} else {
generateBackFace(reward, getRenderedBackface(reward));
}
}
} else {
String imagePath = ImageUtil.getImageRelativePath(reward.getCard(), "", true, false);
File lookup = ImageKeys.hasSetLookup(imagePath) ? ImageKeys.setLookUpFile(imagePath, imagePath + "border") : null;
@@ -355,11 +329,22 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
loaded = false;
if (!ImageCache.getInstance().imageKeyFileExists(reward.getCard().getImageKey(false)))
fetcher.fetchImage(reward.getCard().getImageKey(false), this);
}
}
//preload card back for performance
if (hasbackface) {
if (!ImageCache.getInstance().imageKeyFileExists(reward.getCard().getImageKey(true))) {
fetcher.fetchImage(reward.getCard().getImageKey(true), () -> System.out.println("Backface fetched: " + reward.getCard().getImageKey(true)));
}
}
generateBackFace(reward, getRenderedBackface(reward));
String altKey = reward.getCard().getImageKey(true);
if (ImageCache.getInstance().imageKeyFileExists(altKey)) {
updateBackFace(altKey);
} else {
fetcher.fetchImage(altKey, () -> {
System.out.println("Backface fetched: " + altKey);
updateBackFace(altKey);
});
}
}
break;
@@ -434,10 +419,8 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
Texture t = ImageCache.getInstance().getImage(imageKey, false, true);
isBooster = true;
if (t != null) {
item = new Sprite(new TextureRegion(t));
//setCardImage(t);
onImageFetched();
}
@@ -446,10 +429,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
item = Config.instance().getItemSprite("Deck");
setItemTooltips(item, backSprite, isBooster);
}
}
else{
} else {
item = Config.instance().getItemSprite("Deck");
setItemTooltips(item, backSprite, isBooster);
}
@@ -508,6 +488,9 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
if (isDragging) {
return;
}
if (flipOnClick)
flip();
if (frontSideUp())
@@ -525,6 +508,35 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
hover = false;
}
});
if (Reward.Type.Card.equals(reward.type)) {
addListener(new DragListener() {
private float startY;
@Override
public void dragStart(InputEvent event, float x, float y, int pointer) {
startY = y;
}
@Override
public void drag(InputEvent event, float x, float y, int pointer) {
isDragging = true;
}
@Override
public void dragStop(InputEvent event, float x, float y, int pointer) {
isDragging = false;
if (!frontSideUp() || !hover)
return;
float deltaY = y - startY;
if (deltaY < 0) {
shouldDisplayText = !shouldDisplayText;
switchTooltip();
}
}
});
}
}
}
@@ -536,9 +548,11 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
private void generateBackFace(Reward r, Texture t) {
try {
alternateToolTipImage = new RewardImage(processDrawable(t));
if (holdTooltip != null) {
if (holdTooltip.tooltip_actor.getChildren().size <= 2) {
holdTooltip.tooltip_actor.altcImage = new RewardImage(processDrawable(t));
holdTooltip.tooltip_actor.altcImage = alternateToolTipImage;
holdTooltip.tooltip_actor.addActorAt(2, holdTooltip.tooltip_actor.altcImage);
holdTooltip.tooltip_actor.swapActor(holdTooltip.tooltip_actor.altcImage, holdTooltip.tooltip_actor.cImage);
}
@@ -548,30 +562,66 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
}
}
private void updateBackFace(String key) {
PaperCard cardBack = ImageUtil.getPaperCardFromImageKey(key);
File backFace = ImageKeys.getImageFile(cardBack.getCardAltImageKey());
if (backFace != null) {
try {
Texture back = Forge.getAssets().manager().get(backFace.getPath(), Texture.class, false);
if (back == null) {
Forge.getAssets().manager().load(backFace.getPath(), Texture.class, Forge.getAssets().getTextureFilter());
Forge.getAssets().manager().finishLoadingAsset(backFace.getPath());
back = Forge.getAssets().manager().get(backFace.getPath(), Texture.class, false);
}
if (back != null) {
ImageCache.getInstance().updateSynqCount(backFace, 1);
generateBackFace(reward, back);
} else {
generateBackFace(reward, getRenderedBackface(reward));
}
} catch (Exception e) {
System.err.println("Failed to load image: " + backFace.getPath());
}
};
}
private void switchTooltip() {
if (!Reward.Type.Card.equals(reward.type))
return;
if (GuiBase.isAndroid() || Forge.hasGamepad()) {
if (!reward.getCard().hasBackFace())
return;
if (GuiBase.isAndroid() || Forge.hasGamepad()) {
if (holdTooltip.tooltip_actor.altcImage != null) {
holdTooltip.tooltip_actor.swapActor(holdTooltip.tooltip_actor.cImage, holdTooltip.tooltip_actor.altcImage);
}
} else {
Texture alt = ImageCache.getInstance().getImage(reward.getCard().getImageKey(true), false);
if (hover) {
if (alternate) {
if (alt != null) {
tooltip.setActor(new ComplexTooltip(new RewardImage(processDrawable(alt))));
if (!hover)
return;
if (reward.getCard().hasBackFace() && alternate) {
if (Taltnotext == null)
Taltnotext = renderPlaceholder(new Graphics(), reward.getCard(), true, false);
RewardImage altImage = shouldDisplayText
? new RewardImage(processDrawable(Taltnotext))
: alternateToolTipImage;
if (altImage == null)
return;
tooltip.setActor(new ComplexTooltip(altImage));
} else {
if (Talt == null)
Talt = renderPlaceholder(new Graphics(), reward.getCard(), true);
tooltip.setActor(new ComplexTooltip(new RewardImage(processDrawable(Talt))));
}
} else {
if (toolTipImage != null)
tooltip.setActor(new ComplexTooltip(toolTipImage));
}
if (Tnotext == null)
Tnotext = renderPlaceholder(new Graphics(), reward.getCard(), false, false);
RewardImage image = shouldDisplayText
? new RewardImage(processDrawable(Tnotext))
: toolTipImage;
if (image == null)
return;
tooltip.setActor(new ComplexTooltip(image));
}
}
}
@@ -656,12 +706,16 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
}
}
private Texture renderPlaceholder(Graphics g, PaperCard card, boolean alternate) { //Use CardImageRenderer to output a Texture.
private Texture renderPlaceholder(Graphics g, PaperCard card, boolean alternate) {
return renderPlaceholder(g, card, alternate, true);
}
private Texture renderPlaceholder(Graphics g, PaperCard card, boolean alternate, boolean displayArt) { //Use CardImageRenderer to output a Texture.
if (renderedCount < 1) {
renderedCount++;
//The first time we find a card that has no art, render one out of view to fully initialize CardImageRenderer.
g.begin(preview_w, preview_h);
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(reward.getCard()), false, -(preview_w + 20), 0, preview_w, preview_h, CardRenderer.CardStackPosition.Top, Forge.allowCardBG, true);
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(reward.getCard()), false, -(preview_w + 20), 0, preview_w, preview_h, CardRenderer.CardStackPosition.Top, Forge.allowCardBG, false, false, true, displayArt);
g.end();
}
Matrix4 m = new Matrix4();
@@ -672,7 +726,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
g.begin(preview_w, preview_h);
g.setProjectionMatrix(m);
g.startClip();
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(card), alternate, 0, 0, preview_w, preview_h, CardRenderer.CardStackPosition.Top, Forge.allowCardBG, true);
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(card), alternate, 0, 0, preview_w, preview_h, CardRenderer.CardStackPosition.Top, Forge.allowCardBG, false, false, true, displayArt);
g.end();
g.endClip();
//Rendering ends here. Create a new Pixmap to Texture with mipmaps, otherwise will render as full black.
@@ -847,7 +901,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
}
public void sold() {
//todo add new card to be sold???
// TODO add new card to be sold???
if (sold)
return;
sold = true;
@@ -963,12 +1017,14 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
x = -getWidth() / 2;
}
if (Reward.Type.Card.equals(reward.getType())) {
if (image != null) {
drawCard(batch, image, x, width);
} else if (!loaded) {
if (T == null)
if (!loaded || image == null) {
if (T == null) {
T = renderPlaceholder(new Graphics(), reward.getCard(), false);
}
drawCard(batch, T, x, width);
} else {
drawCard(batch, image, x, width);
}
}
else if (image != null) {
@@ -1048,7 +1104,6 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
batch.setProjectionMatrix(projection);
}
private final Matrix4 computedTransform = new Matrix4();
private final Matrix4 oldTransform = new Matrix4();
private final Matrix4 oldProjectionTransform = new Matrix4();
@@ -1105,7 +1160,6 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
if(reward.type.equals(Reward.Type.CardPack))
{
cLabel.setY(y-70);
}
else

View File

@@ -82,7 +82,7 @@ public class CardImageRenderer {
}
public static void drawFaceDownCard(CardView card, Graphics g, float x, float y, float w, float h) {
//try to draw the card sleeves first
// Try to draw the card sleeves first
FImage sleeves = MatchController.getPlayerSleeve(card.getOwner());
if (sleeves != null)
g.drawImage(sleeves, x, y, w, h);
@@ -91,10 +91,14 @@ public class CardImageRenderer {
}
public static void drawCardImage(Graphics g, CardView card, boolean altState, float x, float y, float w, float h, CardStackPosition pos, boolean useCardBGTexture, boolean showArtist) {
drawCardImage(g, card, altState, x, y, w, h, pos, useCardBGTexture, false, false, showArtist);
drawCardImage(g, card, altState, x, y, w, h, pos, useCardBGTexture, false, false, showArtist, true);
}
public static void drawCardImage(Graphics g, CardView card, boolean altState, float x, float y, float w, float h, CardStackPosition pos, boolean useCardBGTexture, boolean noText, boolean isChoiceList, boolean showArtist) {
drawCardImage(g, card, altState, x, y, w, h, pos, useCardBGTexture, noText, isChoiceList, showArtist, true);
}
public static void drawCardImage(Graphics g, CardView card, boolean altState, float x, float y, float w, float h, CardStackPosition pos, boolean useCardBGTexture, boolean noText, boolean isChoiceList, boolean showArtist, boolean showArtBox) {
updateStaticFields(w, h);
float blackBorderThickness = w * BLACK_BORDER_THICKNESS_RATIO;
@@ -104,7 +108,11 @@ public class CardImageRenderer {
w -= 2 * blackBorderThickness;
h -= 2 * blackBorderThickness;
CardStateView state = altState ? card.getAlternateState() : isChoiceList && card.isSplitCard() ? card.getLeftSplitState() : card.getCurrentState();
CardStateView state = altState
? card.getAlternateState()
: isChoiceList && card.isSplitCard()
? card.getLeftSplitState()
: card.getCurrentState();
final boolean isFaceDown = card.isFaceDown();
final boolean canShow = MatchController.instance.mayView(card);
//override
@@ -123,7 +131,11 @@ public class CardImageRenderer {
//determine colors for borders
final List<DetailColors> borderColors;
if (isFaceDown) {
borderColors = !altState ? ImmutableList.of(DetailColors.FACE_DOWN) : !useCardBGTexture ? ImmutableList.of(DetailColors.FACE_DOWN) : CardDetailUtil.getBorderColors(state, canShow);
borderColors = !altState
? ImmutableList.of(DetailColors.FACE_DOWN)
: !useCardBGTexture
? ImmutableList.of(DetailColors.FACE_DOWN)
: CardDetailUtil.getBorderColors(state, canShow);
} else {
borderColors = CardDetailUtil.getBorderColors(state, canShow);
}
@@ -148,7 +160,7 @@ public class CardImageRenderer {
y += headerHeight;
float artWidth = w - 2 * artInset;
float artHeight = artWidth / CardRenderer.CARD_ART_RATIO;
float artHeight = !showArtBox ? 0f : artWidth / CardRenderer.CARD_ART_RATIO;
float typeBoxHeight = 2 * TYPE_FONT.getCapHeight();
float ptBoxHeight = 0;
float textBoxHeight = h - headerHeight - artHeight - typeBoxHeight - outerBorderThickness - artInset;