mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 02:08:00 +00:00
Add option to download missing card art on the fly
This commit is contained in:
@@ -9,6 +9,8 @@ import android.content.Intent;
|
|||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -28,6 +30,8 @@ import forge.util.FileUtil;
|
|||||||
import forge.util.ThreadUtil;
|
import forge.util.ThreadUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
public class Main extends AndroidApplication {
|
public class Main extends AndroidApplication {
|
||||||
@@ -243,5 +247,11 @@ public class Main extends AndroidApplication {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertToJPEG(InputStream input, OutputStream output) {
|
||||||
|
Bitmap bmp = BitmapFactory.decodeStream(input);
|
||||||
|
bmp.compress(Bitmap.CompressFormat.JPEG, 100, output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import java.awt.image.BufferedImage;
|
|||||||
|
|
||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.game.player.PlayerView;
|
import forge.game.player.PlayerView;
|
||||||
|
import forge.util.ImageFetcher;
|
||||||
|
import forge.util.SwingImageFetcher;
|
||||||
|
|
||||||
|
|
||||||
public abstract class CachedCardImage implements ImageFetcher.Callback {
|
public abstract class CachedCardImage implements ImageFetcher.Callback {
|
||||||
final CardView card;
|
final CardView card;
|
||||||
@@ -11,6 +14,8 @@ public abstract class CachedCardImage implements ImageFetcher.Callback {
|
|||||||
final int width;
|
final int width;
|
||||||
final int height;
|
final int height;
|
||||||
|
|
||||||
|
static final SwingImageFetcher fetcher = new SwingImageFetcher();
|
||||||
|
|
||||||
public CachedCardImage(final CardView card, final Iterable<PlayerView> viewers, final int width, final int height) {
|
public CachedCardImage(final CardView card, final Iterable<PlayerView> viewers, final int width, final int height) {
|
||||||
this.card = card;
|
this.card = card;
|
||||||
this.viewers = viewers;
|
this.viewers = viewers;
|
||||||
@@ -19,7 +24,7 @@ public abstract class CachedCardImage implements ImageFetcher.Callback {
|
|||||||
BufferedImage image = ImageCache.getImageNoDefault(card, viewers, width, height);
|
BufferedImage image = ImageCache.getImageNoDefault(card, viewers, width, height);
|
||||||
if (image == null) {
|
if (image == null) {
|
||||||
String key = card.getCurrentState().getImageKey(viewers);
|
String key = card.getCurrentState().getImageKey(viewers);
|
||||||
ImageFetcher.fetchImage(card, key, this);
|
fetcher.fetchImage(key, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,10 +23,7 @@ import forge.sound.*;
|
|||||||
import forge.toolbox.FOptionPane;
|
import forge.toolbox.FOptionPane;
|
||||||
import forge.toolbox.FSkin;
|
import forge.toolbox.FSkin;
|
||||||
import forge.toolbox.FSkin.SkinImage;
|
import forge.toolbox.FSkin.SkinImage;
|
||||||
import forge.util.BuildInfo;
|
import forge.util.*;
|
||||||
import forge.util.Callback;
|
|
||||||
import forge.util.FileUtil;
|
|
||||||
import forge.util.OperatingSystem;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@@ -42,6 +39,8 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class GuiDesktop implements IGuiBase {
|
public class GuiDesktop implements IGuiBase {
|
||||||
|
private ImageFetcher imageFetcher = new SwingImageFetcher();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRunningOnDesktop() {
|
public boolean isRunningOnDesktop() {
|
||||||
return true;
|
return true;
|
||||||
@@ -63,6 +62,11 @@ public class GuiDesktop implements IGuiBase {
|
|||||||
"../forge-gui/" : "";
|
"../forge-gui/" : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImageFetcher getImageFetcher() {
|
||||||
|
return imageFetcher;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invokeInEdtNow(final Runnable proc) {
|
public void invokeInEdtNow(final Runnable proc) {
|
||||||
proc.run();
|
proc.run();
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ import java.awt.image.WritableRaster;
|
|||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import forge.GuiBase;
|
||||||
import forge.ImageCache;
|
import forge.ImageCache;
|
||||||
import forge.ImageFetcher;
|
import forge.util.ImageFetcher;
|
||||||
import forge.ImageKeys;
|
import forge.ImageKeys;
|
||||||
import forge.game.card.CardView.CardStateView;
|
import forge.game.card.CardView.CardStateView;
|
||||||
import forge.item.InventoryItem;
|
import forge.item.InventoryItem;
|
||||||
@@ -115,7 +116,7 @@ public final class CardPicturePanel extends JPanel implements ImageFetcher.Callb
|
|||||||
CardStateView card = (CardStateView) displayed;
|
CardStateView card = (CardStateView) displayed;
|
||||||
BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(), false);
|
BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(), false);
|
||||||
if (image == null) {
|
if (image == null) {
|
||||||
ImageFetcher.fetchImage(card.getCard(), card.getImageKey(), this);
|
GuiBase.getInterface().getImageFetcher().fetchImage(card.getImageKey(), this);
|
||||||
}
|
}
|
||||||
return FImageUtil.getImage((CardStateView) displayed);
|
return FImageUtil.getImage((CardStateView) displayed);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package forge.util;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public class SwingImageFetcher extends ImageFetcher {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Runnable getDownloadTask(String[] downloadUrls, String destPath, Runnable notifyObservers) {
|
||||||
|
return new SwingDownloadTask(downloadUrls, destPath, notifyObservers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SwingDownloadTask implements Runnable {
|
||||||
|
private final String[] downloadUrls;
|
||||||
|
private final String destPath;
|
||||||
|
private final Runnable notifyObservers;
|
||||||
|
|
||||||
|
public SwingDownloadTask(String[] downloadUrls, String destPath, Runnable notifyObservers) {
|
||||||
|
this.downloadUrls = downloadUrls;
|
||||||
|
this.destPath = destPath;
|
||||||
|
this.notifyObservers = notifyObservers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doFetch(String urlToDownload) throws IOException {
|
||||||
|
URL url = new URL(urlToDownload);
|
||||||
|
System.out.println("Attempting to fetch: " + url);
|
||||||
|
java.net.URLConnection c = url.openConnection();
|
||||||
|
c.setRequestProperty("User-Agent", "");
|
||||||
|
BufferedImage image = ImageIO.read(c.getInputStream());
|
||||||
|
// First, save to a temporary file so that nothing tries to read
|
||||||
|
// a partial download.
|
||||||
|
File destFile = new File(destPath + ".tmp");
|
||||||
|
destFile.mkdirs();
|
||||||
|
ImageIO.write(image, "jpg", destFile);
|
||||||
|
// Now, rename it to the correct name.
|
||||||
|
destFile.renameTo(new File(destPath));
|
||||||
|
System.out.println("Saved image to " + destPath);
|
||||||
|
SwingUtilities.invokeLater(notifyObservers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
for (String urlToDownload : downloadUrls) {
|
||||||
|
try {
|
||||||
|
doFetch(urlToDownload);
|
||||||
|
break;
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Failed to download card [" + destPath + "] image: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,6 +13,10 @@ import org.robovm.apple.foundation.NSAutoreleasePool;
|
|||||||
import org.robovm.apple.uikit.UIApplication;
|
import org.robovm.apple.uikit.UIApplication;
|
||||||
import org.robovm.apple.uikit.UIPasteboard;
|
import org.robovm.apple.uikit.UIPasteboard;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
public class Main extends IOSApplication.Delegate {
|
public class Main extends IOSApplication.Delegate {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -94,5 +98,10 @@ public class Main extends IOSApplication.Delegate {
|
|||||||
public void exit() {
|
public void exit() {
|
||||||
// Not possible on iOS
|
// Not possible on iOS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertToJPEG(InputStream input, OutputStream output) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,9 +13,10 @@ import forge.util.RestartUtil;
|
|||||||
import forge.util.Utils;
|
import forge.util.Utils;
|
||||||
import org.apache.commons.cli.*;
|
import org.apache.commons.cli.*;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.*;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@@ -162,5 +163,11 @@ public class Main {
|
|||||||
public void preventSystemSleep(boolean preventSleep) {
|
public void preventSystemSleep(boolean preventSleep) {
|
||||||
OperatingSystem.preventSystemSleep(preventSleep);
|
OperatingSystem.preventSystemSleep(preventSleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertToJPEG(InputStream input, OutputStream output) throws IOException {
|
||||||
|
BufferedImage image = ImageIO.read(input);
|
||||||
|
ImageIO.write(image, "jpg", output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
40
forge-gui-mobile/src/forge/CachedCardImage.java
Normal file
40
forge-gui-mobile/src/forge/CachedCardImage.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package forge;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
import forge.assets.ImageCache;
|
||||||
|
import forge.game.card.CardView;
|
||||||
|
import forge.item.InventoryItem;
|
||||||
|
import forge.util.ImageFetcher;
|
||||||
|
|
||||||
|
public abstract class CachedCardImage implements ImageFetcher.Callback {
|
||||||
|
protected final String key;
|
||||||
|
static final ImageFetcher fetcher = GuiBase.getInterface().getImageFetcher();
|
||||||
|
|
||||||
|
public CachedCardImage(final CardView card) {
|
||||||
|
key = card.getCurrentState().getImageKey();
|
||||||
|
fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CachedCardImage(final InventoryItem ii) {
|
||||||
|
key = ii.getImageKey(false);
|
||||||
|
fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CachedCardImage(String key) {
|
||||||
|
this.key = key;
|
||||||
|
fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fetch() {
|
||||||
|
Texture image = ImageCache.getImage(key, false);
|
||||||
|
if (image == null) {
|
||||||
|
fetcher.fetchImage(key, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture getImage() {
|
||||||
|
return ImageCache.getImage(key, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void onImageFetched();
|
||||||
|
}
|
||||||
@@ -37,14 +37,11 @@ import forge.sound.IAudioClip;
|
|||||||
import forge.sound.IAudioMusic;
|
import forge.sound.IAudioMusic;
|
||||||
import forge.toolbox.FOptionPane;
|
import forge.toolbox.FOptionPane;
|
||||||
import forge.toolbox.GuiChoose;
|
import forge.toolbox.GuiChoose;
|
||||||
import forge.util.Callback;
|
import forge.util.*;
|
||||||
import forge.util.FileUtil;
|
|
||||||
import forge.util.ThreadUtil;
|
|
||||||
import forge.util.WaitCallback;
|
|
||||||
import forge.util.WaitRunnable;
|
|
||||||
|
|
||||||
public class GuiMobile implements IGuiBase {
|
public class GuiMobile implements IGuiBase {
|
||||||
private final String assetsDir;
|
private final String assetsDir;
|
||||||
|
private ImageFetcher imageFetcher = new LibGDXImageFetcher();
|
||||||
|
|
||||||
public GuiMobile(final String assetsDir0) {
|
public GuiMobile(final String assetsDir0) {
|
||||||
assetsDir = assetsDir0;
|
assetsDir = assetsDir0;
|
||||||
@@ -70,6 +67,11 @@ public class GuiMobile implements IGuiBase {
|
|||||||
return assetsDir;
|
return assetsDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImageFetcher getImageFetcher() {
|
||||||
|
return imageFetcher;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invokeInEdtNow(final Runnable proc) {
|
public void invokeInEdtNow(final Runnable proc) {
|
||||||
proc.run();
|
proc.run();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
|||||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
|
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
|
||||||
import com.badlogic.gdx.graphics.glutils.PixmapTextureData;
|
import com.badlogic.gdx.graphics.glutils.PixmapTextureData;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import forge.CachedCardImage;
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
import forge.Graphics;
|
import forge.Graphics;
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
@@ -28,6 +29,7 @@ import forge.game.card.CardView.CardStateView;
|
|||||||
import forge.game.keyword.Keyword;
|
import forge.game.keyword.Keyword;
|
||||||
import forge.game.card.CounterType;
|
import forge.game.card.CounterType;
|
||||||
import forge.item.IPaperCard;
|
import forge.item.IPaperCard;
|
||||||
|
import forge.item.InventoryItem;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
@@ -51,6 +53,34 @@ public class CardRenderer {
|
|||||||
BehindVert
|
BehindVert
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// class that simplifies the callback logic of CachedCardImage
|
||||||
|
static class RendererCachedCardImage extends CachedCardImage {
|
||||||
|
boolean clearCardArtCache = false;
|
||||||
|
|
||||||
|
public RendererCachedCardImage(CardView card, boolean clearArtCache) {
|
||||||
|
super(card);
|
||||||
|
this.clearCardArtCache = clearArtCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RendererCachedCardImage(InventoryItem ii, boolean clearArtCache) {
|
||||||
|
super(ii);
|
||||||
|
this.clearCardArtCache = clearArtCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RendererCachedCardImage(String key, boolean clearArtCache) {
|
||||||
|
super(key);
|
||||||
|
this.clearCardArtCache = clearArtCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onImageFetched() {
|
||||||
|
ImageCache.clear();
|
||||||
|
if (clearCardArtCache) {
|
||||||
|
cardArtCache.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final FSkinFont NAME_FONT = FSkinFont.get(16);
|
private static final FSkinFont NAME_FONT = FSkinFont.get(16);
|
||||||
public static final float NAME_BOX_TINT = 0.2f;
|
public static final float NAME_BOX_TINT = 0.2f;
|
||||||
public static final float TEXT_BOX_TINT = 0.1f;
|
public static final float TEXT_BOX_TINT = 0.1f;
|
||||||
@@ -124,7 +154,7 @@ public class CardRenderer {
|
|||||||
public static FImageComplex getCardArt(String imageKey, boolean isSplitCard, boolean isHorizontalCard, boolean isAftermathCard) {
|
public static FImageComplex getCardArt(String imageKey, boolean isSplitCard, boolean isHorizontalCard, boolean isAftermathCard) {
|
||||||
FImageComplex cardArt = cardArtCache.get(imageKey);
|
FImageComplex cardArt = cardArtCache.get(imageKey);
|
||||||
if (cardArt == null) {
|
if (cardArt == null) {
|
||||||
Texture image = ImageCache.getImage(imageKey, true);
|
Texture image = new RendererCachedCardImage(imageKey, true).getImage();
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
if (image == ImageCache.defaultImage) {
|
if (image == ImageCache.defaultImage) {
|
||||||
cardArt = CardImageRenderer.forgeArt;
|
cardArt = CardImageRenderer.forgeArt;
|
||||||
@@ -186,7 +216,13 @@ public class CardRenderer {
|
|||||||
public static FImageComplex getAftermathSecondCardArt(String imageKey) {
|
public static FImageComplex getAftermathSecondCardArt(String imageKey) {
|
||||||
FImageComplex cardArt = cardArtCache.get("Aftermath_second_"+imageKey);
|
FImageComplex cardArt = cardArtCache.get("Aftermath_second_"+imageKey);
|
||||||
if (cardArt == null) {
|
if (cardArt == null) {
|
||||||
Texture image = ImageCache.getImage(imageKey, true);
|
Texture image = new CachedCardImage(imageKey) {
|
||||||
|
@Override
|
||||||
|
public void onImageFetched() {
|
||||||
|
ImageCache.clear();
|
||||||
|
cardArtCache.remove("Aftermath_second_" + imageKey);
|
||||||
|
}
|
||||||
|
}.getImage();
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
if (image == ImageCache.defaultImage) {
|
if (image == ImageCache.defaultImage) {
|
||||||
cardArt = CardImageRenderer.forgeArt;
|
cardArt = CardImageRenderer.forgeArt;
|
||||||
@@ -347,7 +383,8 @@ public class CardRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void drawCard(Graphics g, IPaperCard pc, float x, float y, float w, float h, CardStackPosition pos) {
|
public static void drawCard(Graphics g, IPaperCard pc, float x, float y, float w, float h, CardStackPosition pos) {
|
||||||
Texture image = ImageCache.getImage(pc);
|
Texture image = new RendererCachedCardImage(pc, false).getImage();
|
||||||
|
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
if (image == ImageCache.defaultImage) {
|
if (image == ImageCache.defaultImage) {
|
||||||
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos);
|
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos);
|
||||||
@@ -369,7 +406,8 @@ 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) {
|
||||||
Texture image = ImageCache.getImage(card);
|
Texture image = new RendererCachedCardImage(card, false).getImage();;
|
||||||
|
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
if (image == ImageCache.defaultImage) {
|
if (image == ImageCache.defaultImage) {
|
||||||
CardImageRenderer.drawCardImage(g, card, false, x, y, w, h, pos);
|
CardImageRenderer.drawCardImage(g, card, false, x, y, w, h, pos);
|
||||||
|
|||||||
@@ -204,6 +204,10 @@ public class SettingsPage extends TabPage<SettingsScreen> {
|
|||||||
"If turned on, Forge will load all historic format definitions, this may take slightly longer to load at startup."), 3);
|
"If turned on, Forge will load all historic format definitions, this may take slightly longer to load at startup."), 3);
|
||||||
|
|
||||||
//Graphic Options
|
//Graphic Options
|
||||||
|
lstSettings.addItem(new BooleanSetting(FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER,
|
||||||
|
"Download missing card art",
|
||||||
|
"Automatically download missing card art"),
|
||||||
|
4);
|
||||||
lstSettings.addItem(new BooleanSetting(FPref.UI_OVERLAY_FOIL_EFFECT,
|
lstSettings.addItem(new BooleanSetting(FPref.UI_OVERLAY_FOIL_EFFECT,
|
||||||
"Display Foil Overlay",
|
"Display Foil Overlay",
|
||||||
"Displays foil cards with the visual foil overlay effect."),
|
"Displays foil cards with the visual foil overlay effect."),
|
||||||
|
|||||||
62
forge-gui-mobile/src/forge/util/LibGDXImageFetcher.java
Normal file
62
forge-gui-mobile/src/forge/util/LibGDXImageFetcher.java
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package forge.util;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import forge.Forge;
|
||||||
|
import forge.GuiBase;
|
||||||
|
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public class LibGDXImageFetcher extends ImageFetcher {
|
||||||
|
@Override
|
||||||
|
protected Runnable getDownloadTask(String[] downloadUrls, String destPath, Runnable notifyObservers) {
|
||||||
|
return new LibGDXDownloadTask(downloadUrls, destPath, notifyObservers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LibGDXDownloadTask implements Runnable {
|
||||||
|
private final String[] downloadUrls;
|
||||||
|
private final String destPath;
|
||||||
|
private final Runnable notifyObservers;
|
||||||
|
|
||||||
|
LibGDXDownloadTask(String[] downloadUrls, String destPath, Runnable notifyObservers) {
|
||||||
|
this.downloadUrls = downloadUrls;
|
||||||
|
this.destPath = destPath;
|
||||||
|
this.notifyObservers = notifyObservers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doFetch(String urlToDownload) throws IOException {
|
||||||
|
URL url = new URL(urlToDownload);
|
||||||
|
System.out.println("Attempting to fetch: " + url);
|
||||||
|
java.net.URLConnection c = url.openConnection();
|
||||||
|
c.setRequestProperty("User-Agent", "");
|
||||||
|
|
||||||
|
InputStream is = c.getInputStream();
|
||||||
|
// First, save to a temporary file so that nothing tries to read
|
||||||
|
// a partial download.
|
||||||
|
FileHandle destFile = new FileHandle(destPath + ".tmp");
|
||||||
|
System.out.println(destPath);
|
||||||
|
destFile.parent().mkdirs();
|
||||||
|
|
||||||
|
// Conversion to JPEG will be handled differently depending on the platform
|
||||||
|
Forge.getDeviceAdapter().convertToJPEG(is, new FileOutputStream(destFile.file()));
|
||||||
|
destFile.moveTo(new FileHandle(destPath));
|
||||||
|
|
||||||
|
System.out.println("Saved image to " + destPath);
|
||||||
|
GuiBase.getInterface().invokeInEdtLater(notifyObservers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
for (String urlToDownload : downloadUrls) {
|
||||||
|
try {
|
||||||
|
doFetch(urlToDownload);
|
||||||
|
break;
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Failed to download card [" + destPath + "] image: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
package forge.interfaces;
|
package forge.interfaces;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
public interface IDeviceAdapter {
|
public interface IDeviceAdapter {
|
||||||
boolean isConnectedToInternet();
|
boolean isConnectedToInternet();
|
||||||
boolean isConnectedToWifi();
|
boolean isConnectedToWifi();
|
||||||
@@ -10,4 +14,5 @@ public interface IDeviceAdapter {
|
|||||||
void preventSystemSleep(boolean preventSleep);
|
void preventSystemSleep(boolean preventSleep);
|
||||||
void restart();
|
void restart();
|
||||||
void exit();
|
void exit();
|
||||||
|
void convertToJPEG(InputStream input, OutputStream output) throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ import forge.match.HostedMatch;
|
|||||||
import forge.sound.IAudioClip;
|
import forge.sound.IAudioClip;
|
||||||
import forge.sound.IAudioMusic;
|
import forge.sound.IAudioMusic;
|
||||||
import forge.util.Callback;
|
import forge.util.Callback;
|
||||||
|
import forge.util.ImageFetcher;
|
||||||
|
|
||||||
public interface IGuiBase {
|
public interface IGuiBase {
|
||||||
boolean isRunningOnDesktop();
|
boolean isRunningOnDesktop();
|
||||||
boolean isLibgdxPort();
|
boolean isLibgdxPort();
|
||||||
String getCurrentVersion();
|
String getCurrentVersion();
|
||||||
String getAssetsDir();
|
String getAssetsDir();
|
||||||
|
ImageFetcher getImageFetcher();
|
||||||
void invokeInEdtNow(Runnable runnable);
|
void invokeInEdtNow(Runnable runnable);
|
||||||
void invokeInEdtLater(Runnable runnable);
|
void invokeInEdtLater(Runnable runnable);
|
||||||
void invokeInEdtAndWait(Runnable proc);
|
void invokeInEdtAndWait(Runnable proc);
|
||||||
|
|||||||
@@ -1,34 +1,28 @@
|
|||||||
package forge;
|
package forge.util;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import forge.FThreads;
|
||||||
import javax.swing.SwingUtilities;
|
import forge.ImageKeys;
|
||||||
|
import forge.StaticData;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import forge.game.card.CardView;
|
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
import forge.util.FileUtil;
|
|
||||||
import forge.util.ImageUtil;
|
|
||||||
|
|
||||||
public class ImageFetcher {
|
public abstract class ImageFetcher {
|
||||||
private static final ExecutorService threadPool = Executors.newCachedThreadPool();
|
private static final ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||||
private static HashMap<String, HashSet<Callback>> currentFetches = new HashMap<>();
|
private HashMap<String, HashSet<Callback>> currentFetches = new HashMap<>();
|
||||||
private static HashMap<String, String> tokenImages;
|
private HashMap<String, String> tokenImages;
|
||||||
|
|
||||||
public static void fetchImage(final CardView card, final String imageKey, final Callback callback) {
|
public void fetchImage(final String imageKey, final Callback callback) {
|
||||||
FThreads.assertExecutedByEdt(true);
|
FThreads.assertExecutedByEdt(true);
|
||||||
|
|
||||||
if (!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER))
|
if (!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER))
|
||||||
@@ -119,50 +113,12 @@ public class ImageFetcher {
|
|||||||
currentFetches.remove(destPath);
|
currentFetches.remove(destPath);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
threadPool.submit(new DownloadTask(downloadUrls.toArray(new String[0]), destPath, notifyObservers));
|
threadPool.submit(getDownloadTask(downloadUrls.toArray(new String[0]), destPath, notifyObservers));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract Runnable getDownloadTask(String[] toArray, String destPath, Runnable notifyObservers);
|
||||||
|
|
||||||
public static interface Callback {
|
public static interface Callback {
|
||||||
public void onImageFetched();
|
public void onImageFetched();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private static class DownloadTask implements Runnable {
|
|
||||||
private final String[] downloadUrls;
|
|
||||||
private final String destPath;
|
|
||||||
private final Runnable notifyObservers;
|
|
||||||
|
|
||||||
public DownloadTask(String[] downloadUrls, String destPath, Runnable notifyObservers) {
|
|
||||||
this.downloadUrls = downloadUrls;
|
|
||||||
this.destPath = destPath;
|
|
||||||
this.notifyObservers = notifyObservers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doFetch(String urlToDownload) throws IOException {
|
|
||||||
URL url = new URL(urlToDownload);
|
|
||||||
System.out.println("Attempting to fetch: " + url);
|
|
||||||
java.net.URLConnection c = url.openConnection();
|
|
||||||
c.setRequestProperty("User-Agent", "");
|
|
||||||
BufferedImage image = ImageIO.read(c.getInputStream());
|
|
||||||
// First, save to a temporary file so that nothing tries to read
|
|
||||||
// a partial download.
|
|
||||||
File destFile = new File(destPath + ".tmp");
|
|
||||||
destFile.mkdirs();
|
|
||||||
ImageIO.write(image, "jpg", destFile);
|
|
||||||
// Now, rename it to the correct name.
|
|
||||||
destFile.renameTo(new File(destPath));
|
|
||||||
System.out.println("Saved image to " + destPath);
|
|
||||||
SwingUtilities.invokeLater(notifyObservers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
for (String urlToDownload : downloadUrls) {
|
|
||||||
try {
|
|
||||||
doFetch(urlToDownload);
|
|
||||||
break;
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("Failed to download card [" + destPath + "] image: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user