diff --git a/.gitattributes b/.gitattributes
index e0239c2cdc0..43b20a32afc 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -9343,6 +9343,23 @@ res/images/deckeditor/filter_sorcery_n.png -text svneol=unset#image/png
res/images/deckeditor/filter_sorcery_y.png -text svneol=unset#image/png
res/images/deckeditor/filter_white_n.png -text svneol=unset#image/png
res/images/deckeditor/filter_white_y.png -text svneol=unset#image/png
+res/images/skins/default/bg_splash.jpg -text
+res/images/skins/default/btnLdown.png -text
+res/images/skins/default/btnLover.png -text
+res/images/skins/default/btnLup.png -text
+res/images/skins/default/btnMdown.png -text
+res/images/skins/default/btnMover.png -text
+res/images/skins/default/btnMup.png -text
+res/images/skins/default/btnRdown.png -text
+res/images/skins/default/btnRover.png -text
+res/images/skins/default/btnRup.png -text
+res/images/skins/default/font1.ttf -text
+res/images/skins/default/font2.ttf -text
+res/images/skins/default/palette.jpg -text
+res/images/skins/default/settings.txt -text
+res/images/skins/default/texture1.jpg -text
+res/images/skins/default/texture2.jpg -text
+res/images/skins/default/texture3.jpg -text
res/images/symbols-13/0.png -text svneol=unset#image/png
res/images/symbols-13/1.png -text svneol=unset#image/png
res/images/symbols-13/10.png -text svneol=unset#image/png
@@ -10259,6 +10276,10 @@ src/main/java/forge/gui/input/Input_PayManaCostUtil.java svneol=native#text/plai
src/main/java/forge/gui/input/Input_PayManaCost_Ability.java svneol=native#text/plain
src/main/java/forge/gui/input/package-info.java svneol=native#text/plain
src/main/java/forge/gui/package-info.java svneol=native#text/plain
+src/main/java/forge/gui/skin/FButton.java -text
+src/main/java/forge/gui/skin/FPanel.java -text
+src/main/java/forge/gui/skin/FRoundedPanel.java -text
+src/main/java/forge/gui/skin/FSkin.java -text
src/main/java/forge/item/BoosterPack.java -text
src/main/java/forge/item/CardDb.java -text
src/main/java/forge/item/CardPrinted.java -text
diff --git a/.gitignore b/.gitignore
index d18dc44c0d9..f98d220611a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@ res/cardsfolder/cardsfolder.zip
res/decks/AI_o1.dck
res/decks/o1.bdk
res/gui/display_new_layout.xml
+res/images/themes
res/oracleScript.log
res/quest/questData.dat
res/quest/questData.dat.xml
diff --git a/res/images/skins/default/bg_splash.jpg b/res/images/skins/default/bg_splash.jpg
new file mode 100644
index 00000000000..6c929aa0f40
Binary files /dev/null and b/res/images/skins/default/bg_splash.jpg differ
diff --git a/res/images/skins/default/btnLdown.png b/res/images/skins/default/btnLdown.png
new file mode 100644
index 00000000000..1ebc3acbe33
Binary files /dev/null and b/res/images/skins/default/btnLdown.png differ
diff --git a/res/images/skins/default/btnLover.png b/res/images/skins/default/btnLover.png
new file mode 100644
index 00000000000..f1c1d5a88a1
Binary files /dev/null and b/res/images/skins/default/btnLover.png differ
diff --git a/res/images/skins/default/btnLup.png b/res/images/skins/default/btnLup.png
new file mode 100644
index 00000000000..26a28d34e1c
Binary files /dev/null and b/res/images/skins/default/btnLup.png differ
diff --git a/res/images/skins/default/btnMdown.png b/res/images/skins/default/btnMdown.png
new file mode 100644
index 00000000000..d53b4fff943
Binary files /dev/null and b/res/images/skins/default/btnMdown.png differ
diff --git a/res/images/skins/default/btnMover.png b/res/images/skins/default/btnMover.png
new file mode 100644
index 00000000000..7e23fca1e26
Binary files /dev/null and b/res/images/skins/default/btnMover.png differ
diff --git a/res/images/skins/default/btnMup.png b/res/images/skins/default/btnMup.png
new file mode 100644
index 00000000000..f71f8d36d89
Binary files /dev/null and b/res/images/skins/default/btnMup.png differ
diff --git a/res/images/skins/default/btnRdown.png b/res/images/skins/default/btnRdown.png
new file mode 100644
index 00000000000..bd2037c3329
Binary files /dev/null and b/res/images/skins/default/btnRdown.png differ
diff --git a/res/images/skins/default/btnRover.png b/res/images/skins/default/btnRover.png
new file mode 100644
index 00000000000..89568942f54
Binary files /dev/null and b/res/images/skins/default/btnRover.png differ
diff --git a/res/images/skins/default/btnRup.png b/res/images/skins/default/btnRup.png
new file mode 100644
index 00000000000..1f70fe6b5fc
Binary files /dev/null and b/res/images/skins/default/btnRup.png differ
diff --git a/res/images/skins/default/font1.ttf b/res/images/skins/default/font1.ttf
new file mode 100644
index 00000000000..8cd78415278
Binary files /dev/null and b/res/images/skins/default/font1.ttf differ
diff --git a/res/images/skins/default/font2.ttf b/res/images/skins/default/font2.ttf
new file mode 100644
index 00000000000..bd62e60aac9
Binary files /dev/null and b/res/images/skins/default/font2.ttf differ
diff --git a/res/images/skins/default/palette.jpg b/res/images/skins/default/palette.jpg
new file mode 100644
index 00000000000..e874623f4b5
Binary files /dev/null and b/res/images/skins/default/palette.jpg differ
diff --git a/res/images/skins/default/settings.txt b/res/images/skins/default/settings.txt
new file mode 100644
index 00000000000..da39ccc2a4f
--- /dev/null
+++ b/res/images/skins/default/settings.txt
@@ -0,0 +1,16 @@
+# Settings are stored in a key=value format.
+# Color values are stored as RR,GG,BB[,AA] values 0 to 255
+# Dimension values are stored as x,y
+# Incomplete settings will make the file switch to the default theme.
+
+# Texture opacity settings, 0-100
+texture1opacity=100;
+texture2opacity=100;
+texture3opacity=100;
+
+# FRoundedPanel
+shadowColor=150,150,150,150
+borderColor=0,0,0
+shadowDistance=5,5
+shadowThickness=5
+cornerDiameter=20
\ No newline at end of file
diff --git a/res/images/skins/default/texture1.jpg b/res/images/skins/default/texture1.jpg
new file mode 100644
index 00000000000..7c925524eb3
Binary files /dev/null and b/res/images/skins/default/texture1.jpg differ
diff --git a/res/images/skins/default/texture2.jpg b/res/images/skins/default/texture2.jpg
new file mode 100644
index 00000000000..6fc0e6f890f
Binary files /dev/null and b/res/images/skins/default/texture2.jpg differ
diff --git a/res/images/skins/default/texture3.jpg b/res/images/skins/default/texture3.jpg
new file mode 100644
index 00000000000..023287f74d9
Binary files /dev/null and b/res/images/skins/default/texture3.jpg differ
diff --git a/src/main/java/forge/AllZone.java b/src/main/java/forge/AllZone.java
index 87ae6631229..ca6637d6cfa 100644
--- a/src/main/java/forge/AllZone.java
+++ b/src/main/java/forge/AllZone.java
@@ -12,6 +12,7 @@ import forge.card.trigger.TriggerHandler;
import forge.deck.DeckManager;
import forge.game.GameSummary;
import forge.gui.input.InputControl;
+import forge.gui.skin.FSkin;
import forge.model.FGameState;
import forge.properties.ForgeProps;
import forge.properties.NewConstants;
@@ -39,6 +40,9 @@ public final class AllZone implements NewConstants {
// blank
}
+ /** Global SKIN. */
+ private static FSkin SKIN = null;
+
/** Global questData. */
private static forge.quest.data.QuestData questData = null;
@@ -53,7 +57,7 @@ public final class AllZone implements NewConstants {
/** Constant COLOR_CHANGER. */
private static final ColorChanger COLOR_CHANGER = new ColorChanger();
-
+
// Phase is now a prerequisite for CardFactory
/** Global cardFactory. */
private static CardFactoryInterface cardFactory = null;
@@ -494,4 +498,26 @@ public final class AllZone implements NewConstants {
public static ColorChanger getColorChanger() {
return COLOR_CHANGER;
}
+
+ /**
+ *
getSkin.
+ * Gets current display skin. + * + * @return a {@link forge.gui.skin.FSkin} object. + * @since 1.0.15 + */ + public static FSkin getSkin() { + return SKIN; + } + + /** + *setSkin.
+ * Sets current display skin. + * + * @param attackers a {@link forge.gui.skin.FSkin} object. + * @since 1.0.15 + */ + public static void setSkin(final FSkin fs) { + SKIN = fs; + } } //AllZone diff --git a/src/main/java/forge/gui/GuiUtils.java b/src/main/java/forge/gui/GuiUtils.java index eb8cccc3d41..b96c4d34b84 100644 --- a/src/main/java/forge/gui/GuiUtils.java +++ b/src/main/java/forge/gui/GuiUtils.java @@ -17,11 +17,13 @@ import net.slightlymagic.braids.util.UtilFunctions; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; +import java.awt.FontFormatException; import java.awt.Image; import java.awt.Rectangle; import java.awt.Window; import java.awt.image.BufferedImage; import java.io.File; +import java.io.IOException; import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -306,4 +308,24 @@ public final class GuiUtils { bounds.y = (screen.height - bounds.height) / 2; frame.setBounds(bounds); } + + /** + * Attempts to create a font from a filename. Concise error reported + * if exceptions found. + * + * @param {@link java.lang.String} filename + */ + public static Font newFont(String filename) { + File file = new File(filename); + Font ttf = null; + + try { + ttf = Font.createFont(Font.TRUETYPE_FONT,file); + } catch (FontFormatException e) { + System.err.println("GuiUtils > newFont: bad font format \"" + filename + "\""); + } catch (IOException e) { + System.err.println("GuiUtils > newFont: can't find \""+filename+"\""); + } + return ttf; + } } diff --git a/src/main/java/forge/gui/skin/FButton.java b/src/main/java/forge/gui/skin/FButton.java new file mode 100644 index 00000000000..0a5cfce9014 --- /dev/null +++ b/src/main/java/forge/gui/skin/FButton.java @@ -0,0 +1,95 @@ +package forge.gui.skin; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import javax.swing.JButton; +import forge.AllZone; + +/** + * The core JButton used throughout the Forge project. + * Follows skin font and theme button styling. + * + */ +@SuppressWarnings("serial") +public class FButton extends JButton { + protected Image imgL, imgM, imgR; + private int w, h = 0; + private boolean allImagesPresent = false; + private RenderingHints rh; + private FSkin skin; + private AlphaComposite disabledComposite = + AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.25f); + + public FButton(String msg) { + super(msg); + this.skin = AllZone.getSkin(); + this.setOpaque(false); + this.setForeground(skin.txt1a); + this.setBackground(Color.red); + this.setContentAreaFilled(false); + this.setFont(skin.font1.deriveFont(Font.PLAIN,14)); + this.imgL = skin.btnLup.getImage(); + this.imgM = skin.btnMup.getImage(); + this.imgR = skin.btnRup.getImage(); + + rh = new RenderingHints( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON + ); + + if(this.imgL != null && this.imgM != null && this.imgR != null) { + allImagesPresent = true; + } + + this.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseEntered(java.awt.event.MouseEvent evt) { + if(isEnabled()) { + imgL = skin.btnLover.getImage(); + imgM = skin.btnMover.getImage(); + imgR = skin.btnRover.getImage(); + } + } + public void mouseExited(java.awt.event.MouseEvent evt) { + if(isEnabled()) { + imgL = skin.btnLup.getImage(); + imgM = skin.btnMup.getImage(); + imgR = skin.btnRup.getImage(); + } + } + public void mousePressed(java.awt.event.MouseEvent evt) { + if(isEnabled()) { + imgL = skin.btnLdown.getImage(); + imgM = skin.btnMdown.getImage(); + imgR = skin.btnRdown.getImage(); + } + } + }); + } + + protected void paintComponent(Graphics g) { + if(!allImagesPresent) { + return; + } + + Graphics2D g2d = (Graphics2D)g; + g2d.setRenderingHints(rh); + + if(!isEnabled()) { + g2d.setComposite(disabledComposite); + } + + w = this.getWidth(); + h = this.getHeight(); + + g2d.drawImage(imgL,0,0,h,h,null); + g2d.drawImage(imgM,h,0,w - 2*h,h,null); + g2d.drawImage(imgR,w-h,0,h,h,null); + + super.paintComponent(g); + } +} \ No newline at end of file diff --git a/src/main/java/forge/gui/skin/FPanel.java b/src/main/java/forge/gui/skin/FPanel.java new file mode 100644 index 00000000000..204db44b565 --- /dev/null +++ b/src/main/java/forge/gui/skin/FPanel.java @@ -0,0 +1,55 @@ +package forge.gui.skin; + +import java.awt.Graphics; +import java.awt.LayoutManager; +import javax.swing.ImageIcon; +import javax.swing.JPanel; + +/**FPanel.
+ * The core JPanel used throughout the Forge project. + * Allows tiled images and ... + * + */ +@SuppressWarnings("serial") +public class FPanel extends JPanel { + private ImageIcon bgImg = null; + private int w, h, iw, ih, x, y = 0; + + public FPanel() { + super(); + } + + public FPanel(LayoutManager lm) { + this(); + this.setLayout(lm); + } + + protected void paintComponent(Graphics g) { + //System.out.print("\nRepainting. "); + if(this.bgImg != null) { + w = getWidth(); + h = getHeight(); + iw = this.bgImg.getIconWidth(); + ih = this.bgImg.getIconHeight(); + + while(x < w) { + while(y < h) { + g.drawImage(bgImg.getImage(),x,y,null); + y += ih; + } + x += iw; + y = 0; + } + x = 0; + } + + super.paintComponent(g); + } + + public void setBGImg(ImageIcon icon) { + this.bgImg = icon; + if(this.bgImg != null) { + this.setOpaque(false); + } + } +} diff --git a/src/main/java/forge/gui/skin/FRoundedPanel.java b/src/main/java/forge/gui/skin/FRoundedPanel.java new file mode 100644 index 00000000000..7aa844fe187 --- /dev/null +++ b/src/main/java/forge/gui/skin/FRoundedPanel.java @@ -0,0 +1,230 @@ +package forge.gui.skin; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.LayoutManager; +import java.awt.RenderingHints; + +import javax.swing.JPanel; + +import forge.AllZone; + +/**FRoundedPanel.
+ * A subclass of JPanel with optional rounded corners and + * optional drop shadow, for special cases only. FPanel recommended for regular use. + * Limitations - cannot use background image, and single line border only. + * + * Default values provided, later updated from skin settings, and can be + * set dynamically. + * + */ +@SuppressWarnings("serial") +public class FRoundedPanel extends JPanel { + private FSkin skin; + private Color shadowColor = new Color(150,150,150,150); + private Color borderColor = Color.black; + private Dimension shadowDistance = new Dimension(5,5); + private int shadowThickness = 5; + private int cornerRadius = 20; // Note: this number is actually diameter. + + /** + *FRoundedPanel.
+ * + * Constructor, null layout manager. + */ + public FRoundedPanel() { + super(); + this.setOpaque(false); + skin = AllZone.getSkin(); + + Color tempC; + Dimension tempD; + String tempS; + + tempC = parseColorString(skin.getSetting("shadowColor")); + if(tempC != null) { shadowColor = tempC; } + + tempC = parseColorString(skin.getSetting("borderColor")); + if(tempC != null) { borderColor = tempC; } + + tempD = parseDimensionString(skin.getSetting("shadowDistance")); + if(tempD != null) { shadowDistance = tempD; } + + tempS = skin.getSetting("shadowThickness"); + if(tempS != null) { shadowThickness = Integer.parseInt(tempS); } + + tempS = skin.getSetting("cornerRadius"); + if(tempS != null) { cornerRadius = Integer.parseInt(tempS); } + } + + /** + *FRoundedPanel.
+ * + * Constructor. + * @param {@link java.awt.LayoutManager} + */ + public FRoundedPanel(LayoutManager lm) { + this(); + this.setLayout(lm); + } + + /** + *FRoundedPanel.
+ * + * Constructor. + * @param {@link java.awt.Graphics} + */ + protected void paintComponent(Graphics g) { + super.paintComponent(g); + int w = getWidth(); + int h = getHeight(); + + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + // Draw shadow + g2d.setColor(shadowColor); + g2d.setStroke(new BasicStroke(shadowThickness)); + g2d.drawRoundRect( + 0 + (int)shadowDistance.getWidth() + (shadowThickness/2), + 0 + (int)shadowDistance.getHeight() + (shadowThickness/2), + w - (int)shadowDistance.getWidth() - shadowThickness, + h - (int)shadowDistance.getHeight() - shadowThickness, + cornerRadius, cornerRadius); + + // Draw content rectangle (on top of shadow) + g2d.setColor(this.getBackground()); + g2d.fillRoundRect( + 0, 0, + w - shadowThickness, + h - shadowThickness, + cornerRadius, cornerRadius); + + // Stroke border + g2d.setColor(this.borderColor); + g2d.setStroke(new BasicStroke(1)); + g2d.drawRoundRect( + 0,0, + w - shadowThickness, + h - shadowThickness, + cornerRadius, cornerRadius); + } + + /** + *setShadowColor.
+ * Sets color of shadow behind rounded panel. + * + * @param {@link java.awt.Color} + */ + public void setShadowColor(Color c) { + this.shadowColor = c; + } + + /** + *setBorderColor.
+ * Sets color of border around rounded panel. + * + * @param {@link java.awt.Color} + */ + public void setBorderColor(Color c) { + this.borderColor = c; + } + + /** + *setShadowDistance.
+ * Sets distance of shadow from rounded panel. + * + * @param {@link java.lang.Integer} side + */ + public void setShadowDistance(int side) { + this.shadowDistance = new Dimension(side,side); + } + + /** + *setShadowDistance.
+ * Sets distance of shadow from rounded panel. + * + * @param {@link java.lang.Integer} x + * @param {@link java.lang.Integer} y + */ + public void setShadowDistance(int x, int y) { + this.shadowDistance = new Dimension(x,y); + } + + /** + *setShadowDistance.
+ * Sets thickness of rounded panel shadow. + * + * @param {@link java.lang.Integer} t + */ + public void setShadowThickness(int t) { + this.shadowThickness = t; + } + + /** + *setCornerRadius.
+ * Sets radius of each corner on rounded panel. + * + * @param {@link java.lang.Integer} r + */ + public void setCornerRadius(int r) { + if(r < 0) { + r = 0; + } + + this.cornerRadius = r*2; + } + + /** + *parseColorString.
+ * Uses string from settings file to make a new rgba color instance. + * + * @param {@link java.lang.String} s + */ + private Color parseColorString(String s) { + Color c = null; + int r,g,b,a = 0; + String[] temp = s.split(","); + + if(temp.length==3 || temp.length==4) { + r = Integer.parseInt(temp[0]); + g = Integer.parseInt(temp[1]); + b = Integer.parseInt(temp[2]); + if(temp.length==4) { + a = Integer.parseInt(temp[3]); + } + c = new Color(r,g,b,a); + } + + return c; + } + + /** + *parseDimensionString.
+ * Uses string from settings file to make a new dimension instance. + * + * @param {@link java.lang.String} s + */ + private Dimension parseDimensionString(String s) { + Dimension d = null; + int w,h = 0; + String[] temp = s.split(","); + + if(temp.length==2) { + w = Integer.parseInt(temp[0]); + h = Integer.parseInt(temp[0]); + d = new Dimension(w,h); + } + else if(temp.length==1 && !temp[0].equals("")) { + w = Integer.parseInt(temp[0]); + h = w; + d = new Dimension(w,h); + } + + return d; + } +} diff --git a/src/main/java/forge/gui/skin/FSkin.java b/src/main/java/forge/gui/skin/FSkin.java new file mode 100644 index 00000000000..8e0b8f4c7d3 --- /dev/null +++ b/src/main/java/forge/gui/skin/FSkin.java @@ -0,0 +1,268 @@ +package forge.gui.skin; + +import java.awt.Color; +import java.awt.Font; +import java.awt.image.BufferedImage; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Hashtable; + +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; + +import forge.gui.GuiUtils; + +/** + * Assembles settings from selected or default theme as appropriate. + * Saves in a hashtable, access using .get(settingName) method. + * + */ + +public class FSkin { + //===== Public fields + public Font font1 = null; + public Font font2 = null; + public ImageIcon texture1 = null; + public ImageIcon texture2 = null; + public ImageIcon texture3 = null; + public ImageIcon btnLup = null; + public ImageIcon btnMup = null; + public ImageIcon btnRup = null; + public ImageIcon btnLover = null; + public ImageIcon btnMover = null; + public ImageIcon btnRover = null; + public ImageIcon btnLdown = null; + public ImageIcon btnMdown = null; + public ImageIcon btnRdown = null; + + public Color bg1a = Color.red; + public Color bg1b = Color.red; + public Color bg2a = Color.red; + public Color bg2b = Color.red; + public Color bg3a = Color.red; + public Color bg3b = Color.red; + + public Color txt1a = Color.red; + public Color txt1b = Color.red; + public Color txt2a = Color.red; + public Color txt2b = Color.red; + public Color txt3a = Color.red; + public Color txt3b = Color.red; + + //===== Private fields + private final String settingsfile = "settings.txt"; + private final String paletteFile = "palette.jpg"; + private final String font1file = "font1.ttf"; + private final String font2file = "font2.ttf"; + private final String texture1file = "texture1.jpg"; + private final String texture2file = "texture2.jpg"; + private final String texture3file = "texture3.jpg"; + private final String btnLupfile = "btnLup.png"; + private final String btnMupfile = "btnMup.png"; + private final String btnRupfile = "btnRup.png"; + private final String btnLoverfile = "btnLover.png"; + private final String btnMoverfile = "btnMover.png"; + private final String btnRoverfile = "btnRover.png"; + private final String btnLdownfile = "btnLdown.png"; + private final String btnMdownfile = "btnMdown.png"; + private final String btnRdownfile = "btnRdown.png"; + + private ImageIcon tempImg; + private Font tempFont; + private String skin; + private String notfound = "FSkin.java: \""+skin+ + "\" skin can't find "; + private HashtableretrieveImage.
+ * Tries to instantiate an image icon from a filename. + * Error reported if not found. + * + * @param {@link java.lang.String} address + * @return a ImageIcon + */ + private ImageIcon retrieveImage(String address) { + tempImg = new ImageIcon(address); + if(tempImg.getIconWidth()==-1) { + System.err.println(notfound + address); + } + + return tempImg; + } + + /** + *retrieveFont.
+ * Uses GuiUtils to grab a font file at an address. + * Error will be reported by GuiUtils if not found. + * Error also reported by this method if not found. + * + * @param {@link java.lang.String} address + * @return a Font + */ + private Font retrieveFont(String address) { + tempFont = GuiUtils.newFont(address); + + return tempFont; + } + + /** + *getColorFromPixel.
+ * + * @param {@link java.lang.Integer} pixel information + */ + private Color getColorFromPixel(int pixel) { + return new Color( + (pixel & 0x00ff0000) >> 16, + (pixel & 0x0000ff00) >> 8, + (pixel & 0x000000ff) + ); + } + + /** + *getSetting.
+ * Retrieves a specific skin setting. If skin setting is not defined, + * will attempt to use default value. + * + * @param key a {@link java.lang.String} object. + * @return a {@link java.lang.String} object. + */ + public String getSetting(String key) { + String val = null; + + if(customSettings.size() > 1) { + val = customSettings.get(key); + if(val==null) { + System.err.println("FSkin > getSetting: Could not find "+key+ + " setting for "+customSettings.get("name")+" skin!"); + } + } + + if(val==null) { + val = defaultSettings.get(key); + } + + if(val==null) { + System.err.println("FSkin > getSetting: Could not find "+key+ + " in default settings!"); + } + + return val; + } +} diff --git a/src/main/java/forge/properties/ForgePreferences.java b/src/main/java/forge/properties/ForgePreferences.java index 30740833f69..7249cc2379b 100644 --- a/src/main/java/forge/properties/ForgePreferences.java +++ b/src/main/java/forge/properties/ForgePreferences.java @@ -18,6 +18,7 @@ public class ForgePreferences extends Preferences { public boolean uploadDraftAI; public boolean randCFoil; + public String skin; public String laf; public boolean lafFonts; public StackOffsetType stackOffset; @@ -80,6 +81,7 @@ public class ForgePreferences extends Preferences { laf = get("gui.laf", ""); lafFonts = getBoolean("gui.laf.fonts", false); + skin = get("gui.skin","default"); cardOverlay = getBoolean("card.overlay", true); cardSize = CardSizeType.valueOf(get("card.images.size", "medium")); @@ -122,6 +124,7 @@ public class ForgePreferences extends Preferences { set("rand.C.Foil", randCFoil); + set("gui.skin", skin); set("gui.laf", laf); set("gui.laf.fonts", lafFonts); diff --git a/src/main/java/forge/quest/gui/QuestWinLoseHandler.java b/src/main/java/forge/quest/gui/QuestWinLoseHandler.java index c110f62675d..e97baecaace 100644 --- a/src/main/java/forge/quest/gui/QuestWinLoseHandler.java +++ b/src/main/java/forge/quest/gui/QuestWinLoseHandler.java @@ -112,6 +112,15 @@ public class QuestWinLoseHandler extends WinLoseModeHandler { view.btnQuit.setText("Surrender (15 Credits)"); return false; } + else { + view.btnContinue.setVisible(false); + if(wonMatch) { + view.btnQuit.setText("Great!"); + } + else { + view.btnQuit.setText("OK"); + } + } // Win case if(wonMatch) { @@ -145,8 +154,8 @@ public class QuestWinLoseHandler extends WinLoseModeHandler { } // Win or lose, still a chance to win a booster, frequency set in preferences - int cntOutcomes = wonMatch ? model.qData.getWin() : model.qData.getLost(); - if (cntOutcomes % QuestPreferences.getWinsForBooster(model.qData.getDifficultyIndex()) == 0) { + int outcome = wonMatch ? model.qData.getWin() : model.qData.getLost(); + if (outcome % QuestPreferences.getWinsForBooster(model.qData.getDifficultyIndex()) == 0) { awardBooster(); } @@ -344,7 +353,7 @@ public class QuestWinLoseHandler extends WinLoseModeHandler { lblTemp2 = new JLabel(sb.toString()); lblTemp2.setHorizontalAlignment(SwingConstants.CENTER); - lblTemp2.setFont(new Font("Tahoma", Font.PLAIN, 14)); + lblTemp2.setFont(AllZone.getSkin().font2.deriveFont(Font.PLAIN,14)); lblTemp2.setForeground(Color.white); lblTemp2.setIcon(icoTemp); lblTemp2.setIconTextGap(50); @@ -441,7 +450,7 @@ public class QuestWinLoseHandler extends WinLoseModeHandler { ((QuestChallenge)model.qEvent).getTitle() + "\""); lblTemp2 = new JLabel(sb.toString()); - lblTemp2.setFont(new Font("Tahoma", Font.PLAIN, 14)); + lblTemp2.setFont(AllZone.getSkin().font2.deriveFont(Font.PLAIN,14)); lblTemp2.setForeground(Color.white); lblTemp2.setHorizontalAlignment(SwingConstants.CENTER); lblTemp2.setIconTextGap(50); @@ -464,7 +473,7 @@ public class QuestWinLoseHandler extends WinLoseModeHandler { lblTemp1 = new TitleLabel("Gameplay Results"); lblTemp2 = new JLabel("You lose! You have lost 15 credits."); - lblTemp2.setFont(new Font("Tahoma", Font.PLAIN, 14)); + lblTemp2.setFont(AllZone.getSkin().font2.deriveFont(Font.PLAIN,14)); lblTemp2.setForeground(Color.white); lblTemp2.setHorizontalAlignment(SwingConstants.CENTER); lblTemp2.setIconTextGap(50); @@ -530,11 +539,15 @@ public class QuestWinLoseHandler extends WinLoseModeHandler { return credits; } + /** + * JLabel header between reward sections. + * + */ @SuppressWarnings("serial") private class TitleLabel extends JLabel { TitleLabel(String msg) { super(msg); - this.setFont(new Font("Tahoma", Font.ITALIC, 16)); + this.setFont(AllZone.getSkin().font2.deriveFont(Font.ITALIC,16)); this.setPreferredSize(new Dimension(200,40)); this.setHorizontalAlignment(SwingConstants.CENTER); this.setForeground(Color.white); diff --git a/src/main/java/forge/view/swing/ApplicationView.java b/src/main/java/forge/view/swing/ApplicationView.java index fc1bd419e52..be54c774013 100644 --- a/src/main/java/forge/view/swing/ApplicationView.java +++ b/src/main/java/forge/view/swing/ApplicationView.java @@ -17,6 +17,7 @@ import forge.Constant; import forge.ImageCache; import forge.error.ErrorViewer; import forge.game.GameType; +import forge.gui.skin.FSkin; import forge.model.FModel; import forge.properties.ForgePreferences; import forge.view.FView; @@ -42,7 +43,7 @@ public class ApplicationView implements FView { // contract. UtilFunctions.invokeInEventDispatchThreadAndWait(new Runnable() { // NOPMD by Braids on 8/18/11 11:37 PM - public void run() { + public void run() { splashFrame = new SplashFrame(); } }); @@ -77,7 +78,7 @@ public class ApplicationView implements FView { */ @Override - public final void setModel(final FModel model) { + public final void setModel(final FModel model) { try { final ForgePreferences preferences = model.getPreferences(); @@ -97,6 +98,8 @@ public class ApplicationView implements FView { CardSizesAction.set(preferences.cardSize); OldGuiNewGame.upldDrftCheckBox.setSelected(preferences.uploadDraftAI); OldGuiNewGame.foilRandomCheckBox.setSelected(preferences.randCFoil); + + AllZone.setSkin(new FSkin(preferences.skin)); } catch (Exception exn) { Log.error("Error loading preferences: " + exn); diff --git a/src/main/java/forge/view/swing/WinLoseFrame.java b/src/main/java/forge/view/swing/WinLoseFrame.java index 3493aaedeed..942ffb003bb 100644 --- a/src/main/java/forge/view/swing/WinLoseFrame.java +++ b/src/main/java/forge/view/swing/WinLoseFrame.java @@ -1,22 +1,25 @@ package forge.view.swing; import java.awt.Color; -import java.awt.Container; +import java.awt.Component; import java.awt.Dimension; import java.awt.Font; +import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.ActionEvent; -import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingConstants; +import javax.swing.border.AbstractBorder; import forge.AllZone; import forge.Phase; import forge.Player; +import forge.gui.skin.FButton; +import forge.gui.skin.FPanel; import forge.properties.ForgeProps; import forge.properties.NewConstants.LANG.WinLoseFrame.WINLOSETEXT; import forge.quest.data.QuestMatchState; @@ -24,7 +27,7 @@ import forge.quest.data.QuestMatchState; import net.miginfocom.swing.MigLayout; /**WinLoseFrame.
- * Core display for win/lose UI shown after completing a game. + * VIEW - Core display for win/lose UI shown after completing a game. * Uses handlers to customize central panel for various game modes. * */ @@ -34,9 +37,9 @@ public class WinLoseFrame extends JFrame { private QuestMatchState matchState; private WinLoseModeHandler modeHandler; - public JButton btnContinue; - public JButton btnQuit; - public JButton btnRestart; + public FButton btnContinue; + public FButton btnQuit; + public FButton btnRestart; public JLabel lblTitle; public JLabel lblStats; @@ -66,11 +69,14 @@ public class WinLoseFrame extends JFrame { modeHandler = mh; modeHandler.setView(this); matchState = AllZone.getMatchState(); - Container contentPane = this.getContentPane(); - contentPane.setLayout(new MigLayout("wrap, fill")); - contentPane.setBackground(new Color(16,28,50)); + + // Place all content in FPanel + FPanel contentPanel = new FPanel(new MigLayout("wrap, fill, insets 20 0 10 10")); + contentPanel.setBGImg(AllZone.getSkin().texture1); + contentPanel.setBorder(new WinLoseBorder()); + getContentPane().add(contentPanel); - //This needs to be at least 150, or the quit button is off the pane on Mac OS X + //Footer should be at least 150 to keep buttons in-pane on Mac OS X int HEAD_HEIGHT = 150; int FOOT_HEIGHT = 150; int FRAME_WIDTH_SMALL = 300; @@ -79,17 +85,17 @@ public class WinLoseFrame extends JFrame { // Head panel JPanel pnlHead = new JPanel(new MigLayout("wrap, fill")); pnlHead.setOpaque(false); - this.add(pnlHead,"width " + FRAME_WIDTH_SMALL + "!, align center"); + contentPanel.add(pnlHead,"width " + FRAME_WIDTH_SMALL + "!, align center"); lblTitle = new JLabel("WinLoseFrame > lblTitle is broken."); lblTitle.setForeground(Color.white); lblTitle.setHorizontalAlignment(SwingConstants.CENTER); - lblTitle.setFont(new Font("Tahoma", Font.PLAIN, 26)); + lblTitle.setFont(AllZone.getSkin().font1.deriveFont(Font.PLAIN,26)); lblStats = new JLabel("WinLoseFrame > lblStats is broken."); lblStats.setForeground(Color.white); lblStats.setHorizontalAlignment(SwingConstants.CENTER); - lblStats.setFont(new Font("Tahoma", Font.ITALIC, 21)); + lblStats.setFont(AllZone.getSkin().font1.deriveFont(Font.PLAIN,26)); pnlHead.add(lblTitle, "growx"); pnlHead.add(lblStats, "growx"); @@ -99,21 +105,21 @@ public class WinLoseFrame extends JFrame { pnlCustom = new JPanel(new MigLayout("wrap, fillx")); pnlCustom.setBackground(new Color(111,87,59)); pnlCustom.setForeground(Color.white); - this.add(scroller); + contentPanel.add(scroller,"w 96%!, align center, gapleft 2%"); scroller.getViewport().add(pnlCustom); // Foot panel JPanel pnlFoot = new JPanel(new MigLayout("wrap, fill, hidemode 3")); pnlFoot.setOpaque(false); - this.add(pnlFoot,"width " + FRAME_WIDTH_SMALL + "!, align center"); + contentPanel.add(pnlFoot,"width " + FRAME_WIDTH_SMALL + "!, align center"); - this.btnContinue = new WinLoseButton("Continue"); - this.btnRestart = new WinLoseButton("Restart"); - this.btnQuit = new WinLoseButton("Quit"); + this.btnContinue = new FButton("Continue"); + this.btnRestart = new FButton("Restart"); + this.btnQuit = new FButton("Quit"); - pnlFoot.add(btnContinue,"height 30!, gap 0 0 5 5, align center"); - pnlFoot.add(btnRestart,"height 30!, gap 0 0 5 5, align center"); - pnlFoot.add(btnQuit,"height 30!, gap 0 0 5 5, align center"); + pnlFoot.add(btnContinue,"h 36:36, w 150, gap 0 0 5 5, align center"); + pnlFoot.add(btnRestart,"h 36:36, w 150, gap 0 0 5 5, align center"); + pnlFoot.add(btnQuit,"h 36:36, w 150, gap 0 0 5 5, align center"); // Button actions btnQuit.addActionListener(new java.awt.event.ActionListener() { @@ -152,14 +158,14 @@ public class WinLoseFrame extends JFrame { } // Populate custom panel, if necessary. - boolean hasStuff = modeHandler.populateCustomPanel(); - if(!hasStuff) { scroller.setVisible(false); } + boolean hasContents = modeHandler.populateCustomPanel(); + if(!hasContents) { scroller.setVisible(false); } // Size and show frame Dimension screen = this.getToolkit().getScreenSize(); Rectangle bounds = this.getBounds(); - if(hasStuff) { + if(hasContents) { bounds.height = screen.height - 150; scroller.setPreferredSize(new Dimension(FRAME_WIDTH_BIG, screen.height - HEAD_HEIGHT - FOOT_HEIGHT)); @@ -174,7 +180,8 @@ public class WinLoseFrame extends JFrame { bounds.y = (screen.height - bounds.height)/2; } - this.setBounds(bounds); + this.setBackground(AllZone.getSkin().bg1a); + this.setBounds(bounds); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setUndecorated(true); this.setVisible(true); @@ -226,7 +233,7 @@ public class WinLoseFrame extends JFrame { * @return {@link javax.swing.JFrame} display frame */ final JFrame closeWinLoseFrame() { - // issue 147 - keep battlefield up following win/loss + // Issue 147 - keep battlefield up following win/loss JFrame frame = (JFrame) AllZone.getDisplay(); frame.dispose(); frame.setEnabled(true); @@ -234,17 +241,14 @@ public class WinLoseFrame extends JFrame { return frame; } - /** - *WinLoseButton.
- * Private button class to standardize buttons. - * - */ - private class WinLoseButton extends JButton { - WinLoseButton(String msg) { - super(msg); - this.setFont(new Font("Tahoma", Font.PLAIN, 14)); - this.setOpaque(false); - this.setPreferredSize(new Dimension(125,30)); - } + private class WinLoseBorder extends AbstractBorder { + public void paintBorder(Component c, + Graphics g, int x, int y, int width, + int height) { + g.setColor(AllZone.getSkin().txt1a); + g.drawRect(x+1, y+1, width-3, height-3); + g.setColor(AllZone.getSkin().bg1a); + g.drawRect(x+3, y+3, width-7, height-7); + } } }