[Mobile] Card Magnifier

- Add option to display larger version of the hovered card.
This commit is contained in:
Anthony Calosa
2022-02-15 15:31:44 +08:00
parent 1b5de6c2b3
commit ea6aaa1efb
12 changed files with 6012 additions and 5920 deletions

View File

@@ -61,6 +61,7 @@ public class DesktopAdapter implements IDeviceAdapter {
@Override @Override
public void exit() { public void exit() {
Gdx.app.exit(); //can just use Gdx.app.exit for desktop Gdx.app.exit(); //can just use Gdx.app.exit for desktop
System.exit(0);
} }
@Override @Override

View File

@@ -47,8 +47,7 @@ public class StartScene extends UIScene {
} }
public boolean Exit() { public boolean Exit() {
Gdx.app.exit(); Forge.exit(true);
System.exit(0);
return true; return true;
} }

View File

@@ -604,9 +604,9 @@ public class CardRenderer {
} }
} }
public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate) { public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate) {
drawCard(g, card, x, y, w, h, pos, rotate, false, false); drawCard(g, card, x, y, w, h, pos, rotate, false, false, false);
} }
public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate, boolean showAltState, boolean isChoiceList) { public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate, boolean showAltState, boolean isChoiceList, boolean magnify) {
boolean canshow = MatchController.instance.mayView(card); boolean canshow = MatchController.instance.mayView(card);
boolean showsleeves = card.isFaceDown() && card.isInZone(EnumSet.of(ZoneType.Exile)); //fix facedown card image ie gonti lord of luxury boolean showsleeves = card.isFaceDown() && card.isInZone(EnumSet.of(ZoneType.Exile)); //fix facedown card image ie gonti lord of luxury
Texture image = new RendererCachedCardImage(card, false).getImage( showAltState ? card.getAlternateState().getImageKey() : card.getCurrentState().getImageKey()); Texture image = new RendererCachedCardImage(card, false).getImage( showAltState ? card.getAlternateState().getImageKey() : card.getCurrentState().getImageKey());
@@ -628,9 +628,9 @@ public class CardRenderer {
g.setAlphaComposite(oldAlpha); g.setAlphaComposite(oldAlpha);
} else if (showsleeves) { } else if (showsleeves) {
if (!card.isForeTold()) if (!card.isForeTold())
g.drawCardImage(sleeves, crack_overlay, x, y, w, h, card.wasDestroyed(), card.getDamage() > 0); g.drawCardImage(sleeves, crack_overlay, x, y, w, h, card.wasDestroyed(), magnify ? false : card.getDamage() > 0);
else else
g.drawCardImage(image, crack_overlay, x, y, w, h, card.wasDestroyed(), card.getDamage() > 0); g.drawCardImage(image, crack_overlay, x, y, w, h, card.wasDestroyed(), magnify ? false : card.getDamage() > 0);
} else { } else {
if(FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON) if(FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON)
&& (card.getCurrentState().isPhenomenon() || card.getCurrentState().isPlane()) && rotate){ && (card.getCurrentState().isPhenomenon() || card.getCurrentState().isPlane()) && rotate){
@@ -648,19 +648,19 @@ public class CardRenderer {
} else { } else {
if (Forge.enableUIMask.equals("Full") && canshow) { if (Forge.enableUIMask.equals("Full") && canshow) {
if (ImageCache.isBorderlessCardArt(image)) if (ImageCache.isBorderlessCardArt(image))
g.drawCardImage(image, crack_overlay, x, y, w, h, card.wasDestroyed(), card.getDamage() > 0); g.drawCardImage(image, crack_overlay, x, y, w, h, card.wasDestroyed(), magnify ? false : card.getDamage() > 0);
else { else {
boolean t = (card.getCurrentState().getOriginalColors() != card.getCurrentState().getColors()) || card.getCurrentState().hasChangeColors(); boolean t = (card.getCurrentState().getOriginalColors() != card.getCurrentState().getColors()) || card.getCurrentState().hasChangeColors();
g.drawBorderImage(ImageCache.getBorderImage(image.toString(), canshow), ImageCache.borderColor(image), ImageCache.getTint(card, image), x, y, w, h, t); //tint check for changed colors g.drawBorderImage(ImageCache.getBorderImage(image.toString(), canshow), ImageCache.borderColor(image), ImageCache.getTint(card, image), x, y, w, h, t); //tint check for changed colors
g.drawCardImage(ImageCache.croppedBorderImage(image), crack_overlay, x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea, card.wasDestroyed(), card.getDamage() > 0); g.drawCardImage(ImageCache.croppedBorderImage(image), crack_overlay, x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea, card.wasDestroyed(), magnify ? false : card.getDamage() > 0);
} }
} else if (Forge.enableUIMask.equals("Crop") && canshow) { } else if (Forge.enableUIMask.equals("Crop") && canshow) {
g.drawCardImage(ImageCache.croppedBorderImage(image), crack_overlay, x, y, w, h, card.wasDestroyed(), card.getDamage() > 0); g.drawCardImage(ImageCache.croppedBorderImage(image), crack_overlay, x, y, w, h, card.wasDestroyed(), magnify ? false : card.getDamage() > 0);
} else { } else {
if (canshow) if (canshow)
g.drawCardImage(image, crack_overlay, x, y, w, h, card.wasDestroyed(), card.getDamage() > 0); g.drawCardImage(image, crack_overlay, x, y, w, h, card.wasDestroyed(), magnify ? false : card.getDamage() > 0);
else // draw card back sleeves else // draw card back sleeves
g.drawCardImage(sleeves, crack_overlay, x, y, w, h, card.wasDestroyed(), card.getDamage() > 0); g.drawCardImage(sleeves, crack_overlay, x, y, w, h, card.wasDestroyed(), magnify ? false : card.getDamage() > 0);
} }
} }
} }
@@ -684,7 +684,7 @@ public class CardRenderer {
boolean unselectable = !MatchController.instance.isSelectable(card) && MatchController.instance.isSelecting(); boolean unselectable = !MatchController.instance.isSelectable(card) && MatchController.instance.isSelecting();
float cx, cy, cw, ch; float cx, cy, cw, ch;
cx = x; cy = y; cw = w; ch = h; cx = x; cy = y; cw = w; ch = h;
drawCard(g, card, x, y, w, h, pos, false, showAltState, isChoiceList); drawCard(g, card, x, y, w, h, pos, false, showAltState, isChoiceList, false);
float padding = w * PADDING_MULTIPLIER; //adjust for card border float padding = w * PADDING_MULTIPLIER; //adjust for card border
x += padding; x += padding;

View File

@@ -6,8 +6,12 @@ import java.util.Map.Entry;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import forge.animation.ForgeAnimation; import forge.animation.ForgeAnimation;
import forge.assets.FImage; import forge.assets.FImage;
import forge.card.CardRenderer;
import forge.card.CardZoom;
import forge.game.spellability.StackItemView; import forge.game.spellability.StackItemView;
import forge.gui.interfaces.IGuiGame; import forge.gui.interfaces.IGuiGame;
import forge.toolbox.FDisplayObject;
import forge.util.Utils;
import forge.util.collect.FCollectionView; import forge.util.collect.FCollectionView;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@@ -66,7 +70,7 @@ import forge.util.Localizer;
public class MatchScreen extends FScreen { public class MatchScreen extends FScreen {
public static FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS); public static FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS);
private final Map<PlayerView, VPlayerPanel> playerPanels = Maps.newHashMap(); private static final Map<PlayerView, VPlayerPanel> playerPanels = Maps.newHashMap();
private List<VPlayerPanel> playerPanelsList; private List<VPlayerPanel> playerPanelsList;
private final VGameMenu gameMenu; private final VGameMenu gameMenu;
private final VPlayers players; private final VPlayers players;
@@ -79,6 +83,7 @@ public class MatchScreen extends FScreen {
private AbilityEffect activeEffect; private AbilityEffect activeEffect;
private BGAnimation bgAnimation; private BGAnimation bgAnimation;
private ViewWinLose viewWinLose = null; private ViewWinLose viewWinLose = null;
private List<FDisplayObject> potentialListener;
public MatchScreen(List<VPlayerPanel> playerPanels0) { public MatchScreen(List<VPlayerPanel> playerPanels0) {
super(new FMenuBar()); super(new FMenuBar());
@@ -87,6 +92,8 @@ public class MatchScreen extends FScreen {
int humanCount = 0; int humanCount = 0;
playerPanels.clear();
for (VPlayerPanel playerPanel : playerPanels0) { for (VPlayerPanel playerPanel : playerPanels0) {
playerPanels.put(playerPanel.getPlayer(), scroller.add(playerPanel)); playerPanels.put(playerPanel.getPlayer(), scroller.add(playerPanel));
playerPanel.setFlipped(true); playerPanel.setFlipped(true);
@@ -306,7 +313,7 @@ public class MatchScreen extends FScreen {
return bottomPlayerPanel; return bottomPlayerPanel;
} }
public Map<PlayerView, VPlayerPanel> getPlayerPanels() { public static Map<PlayerView, VPlayerPanel> getPlayerPanels() {
return playerPanels; return playerPanels;
} }
@@ -452,6 +459,69 @@ public class MatchScreen extends FScreen {
} }
} }
} }
if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ENABLE_MAGNIFIER)) {
if (Forge.isLandscapeMode() && !GuiBase.isAndroid() && !CardZoom.isOpen() && potentialListener != null) {
for (FDisplayObject object : potentialListener) {
if (object != null) {
if (object instanceof FCardPanel) {
FCardPanel cardPanel = (FCardPanel) object;
try {
if (cardPanel.isHovered()) {
VPlayerPanel vPlayerPanel = getPlayerPanel(cardPanel.getCard().getController());
if (vPlayerPanel == null)
vPlayerPanel = getPlayerPanel(cardPanel.getCard().getOwner());
if (vPlayerPanel != null) {
float cardW = getHeight() * 0.45f;
float cardH = FCardPanel.ASPECT_RATIO * cardW;
float cardX = !ZoneType.Battlefield.equals(cardPanel.getCard().getZone())
? cardPanel.screenPos.x-cardW : cardPanel.screenPos.x+(cardPanel.isTapped()
? cardPanel.getWidth() : cardPanel.getWidth()/1.4f);
if (vPlayerPanel.getSelectedTab() != null && vPlayerPanel.getSelectedTab().isVisible()
&& cardX > vPlayerPanel.getSelectedTab().getDisplayArea().getLeft()) {
cardX = cardPanel.screenPos.x-cardW;
}
if ((cardX+cardW) > scroller.getWidth()+scroller.getLeft())
cardX = cardPanel.screenPos.x-cardW;
if (vPlayerPanel.getCommandZone() != null
&& vPlayerPanel.getCommandZone().isVisible() && cardX > vPlayerPanel.getCommandZone().screenPos.x)
cardX = cardPanel.screenPos.x-cardW;
float cardY = (cardPanel.screenPos.y-cardH)+cardPanel.getHeight();
if (vPlayerPanel.getPlayer() == bottomPlayerPanel.getPlayer()) {
cardY = bottomPlayerPrompt.screenPos.y - cardH;
}
else if (cardY < vPlayerPanel.getField().screenPos.y && vPlayerPanel.getPlayer() != bottomPlayerPanel.getPlayer()) {
cardY = vPlayerPanel.getField().screenPos.y;
if ((cardY+cardH) > bottomPlayerPrompt.screenPos.y)
cardY = bottomPlayerPrompt.screenPos.y - cardH;
}
CardRenderer.drawCard(g, cardPanel.getCard(), cardX, cardY, cardW, cardH, CardRenderer.CardStackPosition.Top, false, false, false, true);
}
}
} catch (Exception e) {
e.printStackTrace();
}
} else if (object instanceof VStack.StackInstanceDisplay) {
try {
CardView cardView = ((VStack.StackInstanceDisplay) object).stackInstance.getSourceCard();
if (object.isHovered() && cardView != null) {
float cardW = getHeight() * 0.45f;
float cardH = FCardPanel.ASPECT_RATIO * cardW;
float cardX = object.screenPos.x-cardW-Utils.scale(4);
float cardY = object.screenPos.y-Utils.scale(2);
if (cardY < topPlayerPanel.getField().screenPos.y)
cardY = topPlayerPanel.getField().screenPos.y;
if ((cardY+cardH) > bottomPlayerPrompt.screenPos.y)
cardY = bottomPlayerPrompt.screenPos.y - cardH;
CardRenderer.drawCard(g, cardView, cardX, cardY, cardW, cardH, CardRenderer.CardStackPosition.Top, false, false, false, true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
} }
@Override @Override
@@ -585,7 +655,7 @@ public class MatchScreen extends FScreen {
} }
} }
public VPlayerPanel getPlayerPanel(final PlayerView playerView) { public static VPlayerPanel getPlayerPanel(final PlayerView playerView) {
return getPlayerPanels().get(playerView); return getPlayerPanels().get(playerView);
} }
@@ -779,16 +849,15 @@ public class MatchScreen extends FScreen {
for (VPlayerPanel playerPanel : playerPanelsList) { for (VPlayerPanel playerPanel : playerPanelsList) {
if (playerPanel.getPlayer().getHasLost()) { if (playerPanel.getPlayer().getHasLost()) {
losers.add(playerPanel); losers.add(playerPanel);
playerPanelsList.remove(playerPanel);
} }
} }
} }
if (!losers.isEmpty()) { if (!losers.isEmpty()) {
float height = 0; float height = 0;
for (VPlayerPanel p : losers) { for (VPlayerPanel p : losers) {
p.clear();
p.noBG = true;
height = p.getAvatar().getHeight(); height = p.getAvatar().getHeight();
p.setVisible(false);
playerPanelsList.remove(p);
System.out.println("Removed panels: "+p.getPlayer().toString()); System.out.println("Removed panels: "+p.getPlayer().toString());
} }
losers.clear(); losers.clear();
@@ -928,4 +997,10 @@ public class MatchScreen extends FScreen {
return false; return false;
} }
} }
@Override
public void buildTouchListeners(float screenX, float screenY, List<FDisplayObject> listeners) {
potentialListener = listeners;
super.buildTouchListeners(screenX, screenY, listeners);
}
} }

View File

@@ -240,8 +240,8 @@ public class VStack extends FDropDown {
} }
} }
private class StackInstanceDisplay extends FDisplayObject { public class StackInstanceDisplay extends FDisplayObject {
private final StackItemView stackInstance; public final StackItemView stackInstance;
private final Color foreColor, backColor; private final Color foreColor, backColor;
private String text; private String text;
private float preferredHeight; private float preferredHeight;

View File

@@ -557,6 +557,12 @@ public class SettingsPage extends TabPage<SettingsScreen> {
localizer.getMessage("lblMatchScrollIndicator"), localizer.getMessage("lblMatchScrollIndicator"),
localizer.getMessage("nlMatchScrollIndicator")), localizer.getMessage("nlMatchScrollIndicator")),
4); 4);
if (!GuiBase.isAndroid()) {
lstSettings.addItem(new BooleanSetting(FPref.UI_ENABLE_MAGNIFIER,
localizer.getMessage("lblEnableMagnifier"),
localizer.getMessage("nlEnableMagnifier")),
4);
}
lstSettings.addItem(new BooleanSetting(FPref.UI_SHOW_FPS, lstSettings.addItem(new BooleanSetting(FPref.UI_SHOW_FPS,
localizer.getMessage("lblShowFPSDisplay"), localizer.getMessage("lblShowFPSDisplay"),
localizer.getMessage("nlShowFPSDisplay")){ localizer.getMessage("nlShowFPSDisplay")){

View File

@@ -1055,6 +1055,8 @@ lblPreloadExtendedArtCards=Preload Extended Art Cards
nlPreloadExtendedArtCards=When enabled, Preloads Extended Art Cards to Cache on Startup (High RAM usage). nlPreloadExtendedArtCards=When enabled, Preloads Extended Art Cards to Cache on Startup (High RAM usage).
lblMatchScrollIndicator=Match Scroll Indicator lblMatchScrollIndicator=Match Scroll Indicator
nlMatchScrollIndicator=When enabled, show the scroll indicator on the match screen. nlMatchScrollIndicator=When enabled, show the scroll indicator on the match screen.
lblEnableMagnifier=Card Magnifier
nlEnableMagnifier=When enabled, displays a larger version of the hovered card during a match.
lblShowFPSDisplay=Show FPS Display lblShowFPSDisplay=Show FPS Display
nlShowFPSDisplay=When enabled, show the FPS Display (Experimental). nlShowFPSDisplay=When enabled, show the FPS Display (Experimental).
lblEnableUnknownCards=Enable Unknown Cards lblEnableUnknownCards=Enable Unknown Cards

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -157,6 +157,7 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
UI_ENABLE_PRELOAD_EXTENDED_ART("false"), UI_ENABLE_PRELOAD_EXTENDED_ART("false"),
UI_ENABLE_BORDER_MASKING("Crop"), UI_ENABLE_BORDER_MASKING("Crop"),
UI_ENABLE_MATCH_SCROLL_INDICATOR("false"), UI_ENABLE_MATCH_SCROLL_INDICATOR("false"),
UI_ENABLE_MAGNIFIER("true"),
UI_SHOW_FPS("false"), UI_SHOW_FPS("false"),
UI_NETPLAY_COMPAT("false"), UI_NETPLAY_COMPAT("false"),
UI_ENABLE_DISPOSE_TEXTURES("false"), UI_ENABLE_DISPOSE_TEXTURES("false"),