From 70c2d18abe09779e540e1c44602193350f31ef24 Mon Sep 17 00:00:00 2001 From: spr Date: Mon, 15 Jul 2013 18:56:39 +0000 Subject: [PATCH] - Converted Skins list to themed combo and added to new Visual Themes section. --- .../home/settings/CSubmenuPreferences.java | 53 +- .../home/settings/VSubmenuPreferences.java | 43 +- src/main/java/forge/gui/toolbox/FSkin.java | 2025 +++++++++-------- 3 files changed, 1041 insertions(+), 1080 deletions(-) diff --git a/src/main/java/forge/gui/home/settings/CSubmenuPreferences.java b/src/main/java/forge/gui/home/settings/CSubmenuPreferences.java index 19760c7562f..4346cf7e41b 100644 --- a/src/main/java/forge/gui/home/settings/CSubmenuPreferences.java +++ b/src/main/java/forge/gui/home/settings/CSubmenuPreferences.java @@ -12,7 +12,6 @@ import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.tuple.Pair; import forge.Command; @@ -56,13 +55,6 @@ public enum CSubmenuPreferences implements ICDoc { this.view = VSubmenuPreferences.SINGLETON_INSTANCE; this.prefs = Singletons.getModel().getPreferences(); - view.getLstChooseSkin().addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - updateSkin(); - } - }); - view.getLstChooseAIProfile().addMouseListener(new MouseAdapter() { @Override public void mouseClicked(final MouseEvent e) { @@ -135,6 +127,7 @@ public enum CSubmenuPreferences implements ICDoc { }); initializeGameLogVerbosityComboBox(); + initializeSkinsComboBox(); } @@ -145,7 +138,6 @@ public enum CSubmenuPreferences implements ICDoc { public void update() { this.view = VSubmenuPreferences.SINGLETON_INSTANCE; this.prefs = Singletons.getModel().getPreferences(); - updateSkinNames(); updateAIProfiles(); view.getCbDevMode().setSelected(prefs.getPrefBoolean(FPref.DEV_MODE_ENABLED)); @@ -212,6 +204,13 @@ public enum CSubmenuPreferences implements ICDoc { GameLogEntryType selectedItem = GameLogEntryType.valueOf(this.prefs.getPref(userSetting)); panel.setComboBox(comboBox, selectedItem); } + private void initializeSkinsComboBox() { + FPref userSetting = FPref.UI_SKIN; + FComboBoxPanel panel = this.view.getSkinsComboBoxPanel(); + JComboBox comboBox = createComboBox(FSkin.getSkinNamesArray(), userSetting); + String selectedItem = this.prefs.getPref(userSetting); + panel.setComboBox(comboBox, selectedItem); + } private JComboBox createComboBox(E[] items, final ForgePreferences.FPref setting) { final JComboBox comboBox = new JComboBox(items); @@ -230,24 +229,7 @@ public enum CSubmenuPreferences implements ICDoc { } }); } - - private void updateSkinNames() { - final VSubmenuPreferences view = VSubmenuPreferences.SINGLETON_INSTANCE; - final String[] uglyNames = FSkin.getSkins().toArray(ArrayUtils.EMPTY_STRING_ARRAY); - final String[] prettyNames = new String[uglyNames.length]; - final String currentName = Singletons.getModel().getPreferences().getPref(FPref.UI_SKIN); - int currentIndex = 0; - - for (int i = 0; i < uglyNames.length; i++) { - prettyNames[i] = WordUtils.capitalize(uglyNames[i].replace('_', ' ')); - if (currentName.equalsIgnoreCase(prettyNames[i])) { currentIndex = i; } - } - - view.getLstChooseSkin().setListData(prettyNames); - view.getLstChooseSkin().setSelectedIndex(currentIndex); - view.getLstChooseSkin().ensureIndexIsVisible(view.getLstChooseSkin().getSelectedIndex()); - } - + private void updateAIProfiles() { final VSubmenuPreferences view = VSubmenuPreferences.SINGLETON_INSTANCE; final List profileNames = AiProfileUtil.getProfilesDisplayList(); @@ -262,23 +244,6 @@ public enum CSubmenuPreferences implements ICDoc { view.getLstChooseAIProfile().setSelectedIndex(currentIndex); view.getLstChooseAIProfile().ensureIndexIsVisible(view.getLstChooseAIProfile().getSelectedIndex()); } - - @SuppressWarnings("serial") - private void updateSkin() { - final VSubmenuPreferences view = VSubmenuPreferences.SINGLETON_INSTANCE; - final String name = view.getLstChooseSkin().getSelectedValue().toString(); - final ForgePreferences prefs = Singletons.getModel().getPreferences(); - if (name.equals(prefs.getPref(FPref.UI_SKIN))) { return; } - - view.getScrChooseSkin().setVisible(false); - view.getLblChooseSkin().setText("Please restart Forge (click here to close)."); - view.getLblChooseSkin().setHoverable(true); - view.getLblChooseSkin().setCommand(new Command() { @Override - public void run() { RestartUtil.restartApplication(null); } }); - - prefs.setPref(FPref.UI_SKIN, name); - prefs.save(); - } private void updateAIProfile() { final VSubmenuPreferences view = VSubmenuPreferences.SINGLETON_INSTANCE; diff --git a/src/main/java/forge/gui/home/settings/VSubmenuPreferences.java b/src/main/java/forge/gui/home/settings/VSubmenuPreferences.java index 4847a500d32..a4280ea05af 100644 --- a/src/main/java/forge/gui/home/settings/VSubmenuPreferences.java +++ b/src/main/java/forge/gui/home/settings/VSubmenuPreferences.java @@ -66,15 +66,6 @@ public enum VSubmenuPreferences implements IVSubmenu { private final FLabel btnDeleteMatchUI = new FLabel.Builder().opaque(true).hoverable(true).text("Reset Match Layout").build(); private final FLabel btnDeleteEditorUI = new FLabel.Builder().opaque(true).hoverable(true).text("Reset Editor Layout").build(); - private final FLabel lblTitleSkin = new FLabel.Builder() - .text("Choose Skin").fontStyle(Font.BOLD).fontSize(14).build(); - - private final JList lstChooseSkin = new FList(); - private final FLabel lblChooseSkin = new FLabel.Builder().fontSize(12).fontStyle(Font.ITALIC) - .text("Various user-created themes for Forge backgrounds, fonts, and colors.") - .fontAlign(SwingConstants.LEFT).build(); - private final JScrollPane scrChooseSkin = new FScrollPane(lstChooseSkin); - private final FLabel lblTitleAIProfile = new FLabel.Builder() .text("Choose AI Personality").fontStyle(Font.BOLD).fontSize(14).build(); @@ -107,6 +98,7 @@ public enum VSubmenuPreferences implements IVSubmenu { private final Map shortcutFields = new HashMap(); + private final FComboBoxPanel cbpSkin = new FComboBoxPanel("Choose Skin:"); private final FComboBoxPanel cbpGameLogEntryType = new FComboBoxPanel("Game Log Verbosity:"); @@ -181,8 +173,14 @@ public enum VSubmenuPreferences implements IVSubmenu { pnlPrefs.add(cbpGameLogEntryType, "w 80%!, gap 10% 0 0 10px, span 2 1"); pnlPrefs.add(new NoteLabel("Changes how much information is displayed in the game log. Sorted by least to most verbose."), regularConstraints); - - // AI Personality Profile Options + + // Themes + pnlPrefs.add(new SectionLabel("Visual Themes"), sectionConstraints + ", gaptop 2%"); + + pnlPrefs.add(cbpSkin, "w 80%!, gap 10% 0 0 10px, span 2 1"); + pnlPrefs.add(new NoteLabel("Change the overall look and feel of Forge (RESTART REQUIRED)."), regularConstraints); + + // AI Personality Profile Options pnlPrefs.add(new SectionLabel("AI Options"), sectionConstraints + ", gaptop 2%"); pnlPrefs.add(lblTitleAIProfile, regularConstraints); @@ -192,9 +190,6 @@ public enum VSubmenuPreferences implements IVSubmenu { // Graphic Options pnlPrefs.add(new SectionLabel("Graphic Options"), sectionConstraints); - pnlPrefs.add(lblTitleSkin, regularConstraints); - pnlPrefs.add(lblChooseSkin, regularConstraints); - pnlPrefs.add(scrChooseSkin, "h 200px!, w 200px!, gap 10% 0 0 2%, wrap"); pnlPrefs.add(cbRandomFoil, regularConstraints); pnlPrefs.add(new NoteLabel("Adds foiled effects to random cards."), regularConstraints); @@ -401,21 +396,6 @@ public enum VSubmenuPreferences implements IVSubmenu { } } - /** @return {@link javax.swing.JList} */ - public final JList getLstChooseSkin() { - return lstChooseSkin; - } - - /** @return {@link forge.gui.toolbox.FLabel} */ - public final FLabel getLblChooseSkin() { - return lblChooseSkin; - } - - /** @return {@link javax.swing.JScrollPane} */ - public final JScrollPane getScrChooseSkin() { - return scrChooseSkin; - } - /** @return {@link javax.swing.JList} */ public final JList getLstChooseAIProfile() { return lstChooseAIProfile; @@ -539,6 +519,11 @@ public enum VSubmenuPreferences implements IVSubmenu { return cbpGameLogEntryType; } + public FComboBoxPanel getSkinsComboBoxPanel() { + return cbpSkin; + } + + //========== Overridden from IVDoc public final FLabel getBtnDeleteMatchUI() { diff --git a/src/main/java/forge/gui/toolbox/FSkin.java b/src/main/java/forge/gui/toolbox/FSkin.java index fda74c24bd5..b1b3982602c 100644 --- a/src/main/java/forge/gui/toolbox/FSkin.java +++ b/src/main/java/forge/gui/toolbox/FSkin.java @@ -1,1007 +1,1018 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * -import forge.view.SplashFrame; - This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.toolbox; - -import java.awt.Color; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import javax.imageio.ImageIO; -import javax.swing.ImageIcon; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.border.LineBorder; - -import forge.FThreads; -import forge.gui.GuiUtils; -import forge.view.FView; - -/** - * Assembles settings from selected or default theme as appropriate. Saves in a - * hashtable, access using .get(settingName) method. - * - */ - -public enum FSkin { - /** Singleton instance of skin. */ - SINGLETON_INSTANCE; - - /** */ - public enum Backgrounds implements SkinProp { /** */ - BG_SPLASH (null), /** */ - BG_TEXTURE (null), /** */ - BG_MATCH (null); /** */ - - private int[] coords; - /** @param xy   int[] coordinates */ - Backgrounds(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** */ - public enum Colors implements SkinProp { /** */ - CLR_THEME (new int[] {70, 10}), /** */ - CLR_BORDERS (new int[] {70, 30}), /** */ - CLR_ZEBRA (new int[] {70, 50}), /** */ - CLR_HOVER (new int[] {70, 70}), /** */ - CLR_ACTIVE (new int[] {70, 90}), /** */ - CLR_INACTIVE (new int[] {70, 110}), /** */ - CLR_TEXT (new int[] {70, 130}), /** */ - CLR_PHASE_INACTIVE_ENABLED (new int[] {70, 150}), /** */ - CLR_PHASE_INACTIVE_DISABLED (new int[] {70, 170}), /** */ - CLR_PHASE_ACTIVE_ENABLED (new int[] {70, 190}), /** */ - CLR_PHASE_ACTIVE_DISABLED (new int[] {70, 210}), /** */ - CLR_THEME2 (new int[] {70, 230}), /** */ - CLR_OVERLAY (new int[] {70, 250}); - - private int[] coords; - /** @param xy   int[] coordinates */ - Colors(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** int[] can hold [xcoord, ycoord, width, height, newwidth, newheight]. */ - public enum ZoneImages implements SkinProp { /** */ - ICO_HAND (new int[] {280, 40, 40, 40}), /** */ - ICO_LIBRARY (new int[] {280, 0, 40, 40}), /** */ - ICO_EXILE (new int[] {320, 40, 40, 40}), /** */ - ICO_FLASHBACK (new int[] {280, 80, 40, 40}), /** */ - ICO_GRAVEYARD (new int[] {320, 0, 40, 40}), /** */ - ICO_POISON (new int[] {320, 80, 40, 40}); - - private int[] coords; - /** @param xy   int[] coordinates */ - ZoneImages(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** int[] can hold [xcoord, ycoord, width, height, newwidth, newheight]. */ - public enum ManaImages implements SkinProp { /** */ - IMG_BLACK (new int[] {360, 160, 40, 40}), /** */ - IMG_RED (new int[] {400, 160, 40, 40}), /** */ - IMG_COLORLESS (new int[] {440, 160, 40, 40}), /** */ - IMG_BLUE (new int[] {360, 200, 40, 40}), /** */ - IMG_GREEN (new int[] {400, 200, 40, 40}), /** */ - IMG_WHITE (new int[] {440, 200, 40, 40}), /** */ - IMG_2B (new int[] {360, 400, 40, 40}), /** */ - IMG_2G (new int[] {400, 400, 40, 40}), /** */ - IMG_2R (new int[] {440, 400, 40, 40}), /** */ - IMG_2U (new int[] {440, 360, 40, 40}), /** */ - IMG_2W (new int[] {400, 360, 40, 40}), /** */ - IMG_BLACK_GREEN (new int[] {360, 240, 40, 40}), /** */ - IMG_BLACK_RED (new int[] {400, 240, 40, 40}), /** */ - IMG_GREEN_BLUE (new int[] {360, 280, 40, 40}), /** */ - IMG_GREEN_WHITE (new int[] {440, 280, 40, 40}), /** */ - IMG_RED_GREEN (new int[] {360, 320, 40, 40}), /** */ - IMG_RED_WHITE (new int[] {400, 320, 40, 40}), /** */ - IMG_BLUE_BLACK (new int[] {440, 240, 40, 40}), /** */ - IMG_BLUE_RED (new int[] {440, 320, 40, 40}), /** */ - IMG_WHITE_BLACK (new int[] {400, 280, 40, 40}), /** */ - IMG_WHITE_BLUE (new int[] {360, 360, 40, 40}), /** */ - IMG_PHRYX_BLUE (new int[] {320, 200, 40, 40}), /** */ - IMG_PHRYX_WHITE (new int[] {320, 240, 40, 40}), /** */ - IMG_PHRYX_RED (new int[] {320, 280, 40, 40}), /** */ - IMG_PHRYX_GREEN (new int[] {320, 320, 40, 40}), /** */ - IMG_PHRYX_BLACK (new int[] {320, 360, 40, 40}); - - private int[] coords; - /** @param xy   int[] coordinates */ - ManaImages(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** int[] can hold [xcoord, ycoord, width, height, newwidth, newheight]. */ - public enum ColorlessManaImages implements SkinProp { /** */ - IMG_0 (new int[] {640, 200, 20, 20}), /** */ - IMG_1 (new int[] {660, 200, 20, 20}), /** */ - IMG_2 (new int[] {640, 220, 20, 20}), /** */ - IMG_3 (new int[] {660, 220, 20, 20}), /** */ - IMG_4 (new int[] {640, 240, 20, 20}), /** */ - IMG_5 (new int[] {660, 240, 20, 20}), /** */ - IMG_6 (new int[] {640, 260, 20, 20}), /** */ - IMG_7 (new int[] {660, 260, 20, 20}), /** */ - IMG_8 (new int[] {640, 280, 20, 20}), /** */ - IMG_9 (new int[] {660, 280, 20, 20}), /** */ - IMG_10 (new int[] {640, 300, 20, 20}), /** */ - IMG_11 (new int[] {660, 300, 20, 20}), /** */ - IMG_12 (new int[] {640, 320, 20, 20}), /** */ - IMG_15 (new int[] {660, 340, 20, 20}), /** */ - IMG_16 (new int[] {640, 360, 20, 20}), /** */ - IMG_20 (new int[] {640, 400, 20, 20}), /** */ - IMG_X (new int[] {640, 420, 20, 20}), /** */ - IMG_Y (new int[] {660, 420, 20, 20}), /** */ - IMG_Z (new int[] {640, 440, 20, 20}); - - private int[] coords; - /** @param xy   int[] coordinates */ - ColorlessManaImages(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** int[] can hold [xcoord, ycoord, width, height, newwidth, newheight]. */ - public enum GameplayImages implements SkinProp { /** */ - IMG_SNOW (new int[] {320, 160, 40, 40}), /** */ - IMG_TAP (new int[] {660, 440, 20, 20}), /** */ - IMG_UNTAP (new int[] {640, 460, 20, 20}), /** */ - IMG_SLASH (new int[] {660, 400, 10, 13}), /** */ - IMG_ATTACK (new int[] {160, 320, 80, 80, 32, 32}), /** */ - IMG_DEFEND (new int[] {160, 400, 80, 80, 32, 32}), /** */ - IMG_SUMMONSICK (new int[] {240, 400, 80, 80, 32, 32}), /** */ - IMG_PHASING (new int[] {240, 320, 80, 80, 32, 32}), /** */ - IMG_COSTRESERVED (new int[] {240, 240, 80, 80, 40, 40}), /** */ - IMG_COUNTERS1 (new int[] {0, 320, 80, 80}), /** */ - IMG_COUNTERS2 (new int[] {0, 400, 80, 80}), /** */ - IMG_COUNTERS3 (new int[] {80, 320, 80, 80}), /** */ - IMG_COUNTERS_MULTI (new int[] {80, 400, 80, 80}); - - private int[] coords; - /** @param xy   int[] coordinates */ - GameplayImages(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** */ - public enum Foils implements SkinProp { /** */ - FOIL_01 (new int[] {0, 0, 400, 570}), /** */ - FOIL_02 (new int[] {400, 0, 400, 570}), /** */ - FOIL_03 (new int[] {0, 570, 400, 570}), /** */ - FOIL_04 (new int[] {400, 570, 400, 570}), /** */ - FOIL_05 (new int[] {0, 1140, 400, 570}), /** */ - FOIL_06 (new int[] {400, 1140, 400, 570}), /** */ - FOIL_07 (new int[] {0, 1710, 400, 570}), /** */ - FOIL_08 (new int[] {400, 1710, 400, 570}), /** */ - FOIL_09 (new int[] {0, 2280, 400, 570}), /** */ - FOIL_10 (new int[] {400, 2280, 400, 570}); /** */ - - private int[] coords; - /** @param xy   int[] coordinates */ - Foils(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - public enum OldFoils implements SkinProp { /** */ - FOIL_11 (new int[] {0, 0, 400, 570}), /** */ - FOIL_12 (new int[] {400, 0, 400, 570}), /** */ - FOIL_13 (new int[] {0, 570, 400, 570}), /** */ - FOIL_14 (new int[] {400, 570, 400, 570}), /** */ - FOIL_15 (new int[] {0, 1140, 400, 570}), /** */ - FOIL_16 (new int[] {400, 1140, 400, 570}), /** */ - FOIL_17 (new int[] {0, 1710, 400, 570}), /** */ - FOIL_18 (new int[] {400, 1710, 400, 570}), /** */ - FOIL_19 (new int[] {0, 2280, 400, 570}), /** */ - FOIL_20 (new int[] {400, 2280, 400, 570}); /** */ - - private int[] coords; - /** @param xy   int[] coordinates */ - OldFoils(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** */ - public enum DockIcons implements SkinProp { /** */ - ICO_SHORTCUTS (new int[] {160, 640, 80, 80}), /** */ - ICO_SETTINGS (new int[] {80, 640, 80, 80}), /** */ - ICO_ENDTURN (new int[] {320, 640, 80, 80}), /** */ - ICO_CONCEDE (new int[] {240, 640, 80, 80}), /** */ - ICO_REVERTLAYOUT (new int[] {400, 720, 80, 80}), /** */ - ICO_OPENLAYOUT (new int[] {0, 800, 80, 80}), /** */ - ICO_SAVELAYOUT (new int[] {80, 800, 80, 80}), /** */ - ICO_DECKLIST (new int[] {400, 640, 80, 80}), /** */ - ICO_ALPHASTRIKE (new int[] {160, 800, 80, 80}), /** */ - ICO_ARCSOFF (new int[] {240, 800, 80, 80}), /** */ - ICO_ARCSON (new int[] {320, 800, 80, 80}), /** */ - ICO_ARCSHOVER (new int[] {400, 800, 80, 80}); - - private int[] coords; - /** @param xy   int[] coordinates */ - DockIcons(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** */ - public enum QuestIcons implements SkinProp { /** */ - ICO_ZEP (new int[] {0, 480, 80, 80}), /** */ - ICO_GEAR (new int[] {80, 480, 80, 80}), /** */ - ICO_GOLD (new int[] {160, 480, 80, 80}), /** */ - ICO_ELIXIR (new int[] {240, 480, 80, 80}), /** */ - ICO_BOOK (new int[] {320, 480, 80, 80}), /** */ - ICO_BOTTLES (new int[] {400, 480, 80, 80}), /** */ - ICO_BOX (new int[] {480, 480, 80, 80}), /** */ - ICO_COIN (new int[] {560, 480, 80, 80}), /** */ - - ICO_FOX (new int[] {0, 560, 80, 80}), /** */ - ICO_LEAF (new int[] {80, 560, 80, 80}), /** */ - ICO_LIFE (new int[] {160, 560, 80, 80}), /** */ - ICO_COINSTACK (new int[] {240, 560, 80, 80}), /** */ - ICO_MAP (new int[] {320, 560, 80, 80}), /** */ - ICO_NOTES (new int[] {400, 560, 80, 80}), /** */ - ICO_HEART (new int[] {480, 560, 80, 80}), /** */ - ICO_BREW (new int[] {560, 560, 80, 80}), /** */ - - ICO_MINUS (new int[] {560, 640, 80, 80}), /** */ - ICO_PLUS (new int[] {480, 640, 80, 80}), /** */ - ICO_PLUSPLUS (new int[] {480, 720, 80, 80}); - - private int[] coords; - /** @param xy   int[] coordinates */ - QuestIcons(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** */ - public enum InterfaceIcons implements SkinProp { /** */ - ICO_DELETE (new int[] {640, 480, 20, 20}), /** */ - ICO_DELETE_OVER (new int[] {660, 480, 20, 20}), /** */ - ICO_EDIT (new int[] {640, 500, 20, 20}), /** */ - ICO_EDIT_OVER (new int[] {660, 500, 20, 20}), /** */ - ICO_OPEN (new int[] {660, 520, 20, 20}), /** */ - ICO_MINUS (new int[] {660, 620, 20, 20}), /** */ - ICO_NEW (new int[] {660, 540, 20, 20}), /** */ - ICO_PLUS (new int[] {660, 600, 20, 20}), /** */ - ICO_PRINT (new int[] {660, 640, 20, 20}), /** */ - ICO_SAVE (new int[] {660, 560, 20, 20}), /** */ - ICO_SAVEAS (new int[] {660, 580, 20, 20}), /** */ - ICO_UNKNOWN (new int[] {0, 720, 80, 80}), /** */ - ICO_LOGO (new int[] {480, 0, 200, 200}), /** */ - ICO_FLIPCARD (new int[] {400, 0, 80, 120}), /** */ - ICO_FAVICON (new int[] {0, 640, 80, 80}); - - private int[] coords; - /** @param xy   int[] coordinates */ - InterfaceIcons(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** */ - public enum LayoutImages implements SkinProp { /** */ - IMG_HANDLE (new int[] {320, 450, 80, 20}), /** */ - IMG_CUR_L (new int[] {564, 724, 32, 32}), /** */ - IMG_CUR_R (new int[] {564, 764, 32, 32}), /** */ - IMG_CUR_T (new int[] {604, 724, 32, 32}), /** */ - IMG_CUR_B (new int[] {604, 764, 32, 32}), /** */ - IMG_CUR_TAB (new int[] {644, 764, 32, 32}); - - private int[] coords; - /** @param xy   int[] coordinates */ - LayoutImages(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** */ - public enum EditorImages implements SkinProp { /** */ - IMG_ARTIFACT (new int[] {280, 720, 40, 40}), /** */ - IMG_CREATURE (new int[] {240, 720, 40, 40}), /** */ - IMG_ENCHANTMENT (new int[] {320, 720, 40, 40}), /** */ - IMG_INSTANT (new int[] {360, 720, 40, 40}), /** */ - IMG_LAND (new int[] {120, 720, 40, 40}), /** */ - IMG_MULTI (new int[] {80, 720, 40, 40}), /** */ - IMG_PLANESWALKER (new int[] {200, 720, 40, 40}), /** */ - IMG_PACK (new int[] {80, 760, 40, 40}), /** */ - IMG_SORCERY (new int[] {160, 720, 40, 40}); - - private int[] coords; - /** @param xy   int[] coordinates */ - EditorImages(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** */ - public enum ButtonImages implements SkinProp { /** */ - IMG_BTN_START_UP (new int[] {480, 200, 160, 80}), /** */ - IMG_BTN_START_OVER (new int[] {480, 280, 160, 80}), /** */ - IMG_BTN_START_DOWN (new int[] {480, 360, 160, 80}), /** */ - - IMG_BTN_UP_LEFT (new int[] {80, 0, 40, 40}), /** */ - IMG_BTN_UP_CENTER (new int[] {120, 0, 1, 40}), /** */ - IMG_BTN_UP_RIGHT (new int[] {160, 0, 40, 40}), /** */ - - IMG_BTN_OVER_LEFT (new int[] {80, 40, 40, 40}), /** */ - IMG_BTN_OVER_CENTER (new int[] {120, 40, 1, 40}), /** */ - IMG_BTN_OVER_RIGHT (new int[] {160, 40, 40, 40}), /** */ - - IMG_BTN_DOWN_LEFT (new int[] {80, 80, 40, 40}), /** */ - IMG_BTN_DOWN_CENTER (new int[] {120, 80, 1, 40}), /** */ - IMG_BTN_DOWN_RIGHT (new int[] {160, 80, 40, 40}), /** */ - - IMG_BTN_FOCUS_LEFT (new int[] {80, 120, 40, 40}), /** */ - IMG_BTN_FOCUS_CENTER (new int[] {120, 120, 1, 40}), /** */ - IMG_BTN_FOCUS_RIGHT (new int[] {160, 120, 40, 40}), /** */ - - IMG_BTN_TOGGLE_LEFT (new int[] {80, 160, 40, 40}), /** */ - IMG_BTN_TOGGLE_CENTER (new int[] {120, 160, 1, 40}), /** */ - IMG_BTN_TOGGLE_RIGHT (new int[] {160, 160, 40, 40}), /** */ - - IMG_BTN_DISABLED_LEFT (new int[] {80, 200, 40, 40}), /** */ - IMG_BTN_DISABLED_CENTER (new int[] {120, 200, 1, 40}), /** */ - IMG_BTN_DISABLED_RIGHT (new int[] {160, 200, 40, 40}); - - private int[] coords; - /** @param xy   int[] coordinates */ - ButtonImages(final int[] xy) { this.coords = xy; } - /** @return int[] */ - @Override - public int[] getCoords() { return coords; } - } - - /** Properties of various components that make up the skin. - * This interface allows all enums to be under the same roof. - * It also enforces a getter for coordinate locations in sprites. */ - public interface SkinProp { - /** @return int[] */ - int[] getCoords(); - } - - private static Map icons; - private static Map images; - private static Map colors; - - private static Map plainFonts; - private static Map boldFonts; - private static Map italicFonts; - private static Map avatars; - - private static final String - FILE_SKINS_DIR = "res/skins/", - FILE_ICON_SPRITE = "sprite_icons.png", - FILE_FOIL_SPRITE = "sprite_foils.png", - FILE_OLD_FOIL_SPRITE = "sprite_old_foils.png", - FILE_AVATAR_SPRITE = "sprite_avatars.png", - FILE_FONT = "font1.ttf", - FILE_SPLASH = "bg_splash.png", - FILE_MATCH_BG = "bg_match.jpg", - FILE_TEXTURE_BG = "bg_texture.jpg", - DEFAULT_DIR = FILE_SKINS_DIR + "default/"; - - private static String preferredDir; - private static String preferredName; - private static Font font; - private static BufferedImage bimDefaultSprite, bimPreferredSprite, bimFoils, - bimOldFoils, bimDefaultAvatars, bimPreferredAvatars; - private static int x0, y0, w0, h0, newW, newH, preferredW, preferredH; - private static int[] tempCoords; - - /** - * Loads a "light" version of FSkin, just enough for the splash screen: - * skin name. Generates custom skin settings, fonts, and backgrounds. - * - * - * @param skinName - * the skin name - */ - public static void loadLight(final String skinName) { - // No need for this method to be loaded while on the EDT. - FThreads.assertExecutedByEdt(false); - - // Non-default (preferred) skin name and dir. - FSkin.preferredName = skinName.toLowerCase().replace(' ', '_'); - FSkin.preferredDir = FILE_SKINS_DIR + preferredName + "/"; - - if (FSkin.icons != null) { FSkin.icons.clear(); } - if (FSkin.images != null) { FSkin.images.clear(); } - if (FSkin.colors != null) { FSkin.colors.clear(); } - - FSkin.icons = new HashMap(); - FSkin.images = new HashMap(); - FSkin.colors = new HashMap(); - - final File f = new File(preferredDir + FILE_SPLASH); - if (!f.exists()) { - FSkin.loadLight("default"); - } - else { - final BufferedImage img; - try { - img = ImageIO.read(f); - - final int h = img.getHeight(); - final int w = img.getWidth(); - - FSkin.setIcon(Backgrounds.BG_SPLASH, img.getSubimage(0, 0, w, h - 100)); - - UIManager.put("ProgressBar.background", FSkin.getColorFromPixel(img.getRGB(25, h - 75))); - UIManager.put("ProgressBar.selectionBackground", FSkin.getColorFromPixel(img.getRGB(75, h - 75))); - UIManager.put("ProgressBar.foreground", FSkin.getColorFromPixel(img.getRGB(25, h - 25))); - UIManager.put("ProgressBar.selectionForeground", FSkin.getColorFromPixel(img.getRGB(75, h - 25))); - UIManager.put("ProgressBar.border", new LineBorder(Color.BLACK, 0)); - } catch (final IOException e) { - e.printStackTrace(); - } - } - } - - public static void setProgessBarMessage(final String message) { - setProgessBarMessage(message, 0); - } - public static void setProgessBarMessage(final String message, final int cnt) { - final FProgressBar barProgress = FView.SINGLETON_INSTANCE.getSplash().getProgressBar(); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - if ( cnt > 0 ) { - barProgress.reset(); - barProgress.setMaximum(cnt); - } - barProgress.setShowETA(false); - barProgress.setShowCount(cnt > 0); - barProgress.setDescription(message); - - } - }); - } - - /** - * Loads two sprites: the default (which should be a complete - * collection of all symbols) and the preferred (which may be - * incomplete). - * - * Font must be present in the skin folder, and will not - * be replaced by default. The fonts are pre-derived - * in this method and saved in a HashMap for future access. - * - * Color swatches must be present in the preferred - * sprite, and will not be replaced by default. - * - * Background images must be present in skin folder, - * and will not be replaced by default. - * - * Icons, however, will be pulled from the two sprites. Obviously, - * preferred takes precedence over default, but if something is - * missing, the default picture is retrieved. - */ - public static void loadFull() { - // No need for this method to be loaded while on the EDT. - FThreads.assertExecutedByEdt(false); - - // Preferred skin name must be called via loadLight() method, - // which does some cleanup and init work. - if (FSkin.preferredName.isEmpty()) { FSkin.loadLight("default"); } - - // Everything OK? - - final FProgressBar barProgress = FView.SINGLETON_INSTANCE.getSplash().getProgressBar(); - setProgessBarMessage("Processing image sprites: ", 5); - - - // Grab and test various sprite files. - final File f1 = new File(DEFAULT_DIR + FILE_ICON_SPRITE); - final File f2 = new File(preferredDir + FILE_ICON_SPRITE); - final File f3 = new File(DEFAULT_DIR + FILE_FOIL_SPRITE); - final File f4 = new File(DEFAULT_DIR + FILE_AVATAR_SPRITE); - final File f5 = new File(preferredDir + FILE_AVATAR_SPRITE); - final File f6 = new File(DEFAULT_DIR + FILE_OLD_FOIL_SPRITE); - - try { - bimDefaultSprite = ImageIO.read(f1); - barProgress.increment(); - bimPreferredSprite = ImageIO.read(f2); - barProgress.increment(); - bimFoils = ImageIO.read(f3); - barProgress.increment(); - bimOldFoils = f6.exists() ? ImageIO.read(f6) : ImageIO.read(f3); - barProgress.increment(); - bimDefaultAvatars = ImageIO.read(f4); - - if (f5.exists()) { bimPreferredAvatars = ImageIO.read(f5); } - - barProgress.increment(); - - preferredH = bimPreferredSprite.getHeight(); - preferredW = bimPreferredSprite.getWidth(); - } - catch (final Exception e) { - System.err.println("FSkin$loadFull: Missing a sprite (default icons, " - + "preferred icons, or foils."); - e.printStackTrace(); - } - - // Pre-derive most fonts (plain, bold, and italic). - // Exceptions handled inside method. - FSkin.font = GuiUtils.newFont(FILE_SKINS_DIR + preferredName + "/" + FILE_FONT); - plainFonts = new HashMap(); - boldFonts = new HashMap(); - italicFonts = new HashMap(); - for (int i = 10; i <= 22; i++) { setFont(i); } - for (int i = 10; i <= 20; i += 2) { setBoldFont(i); } - for (int i = 12; i <= 14; i += 2) { setItalicFont(i); } - - // Put various images into map (except sprite and splash). - // Exceptions handled inside method. - FSkin.setIcon(Backgrounds.BG_TEXTURE, preferredDir + FILE_TEXTURE_BG); - FSkin.setIcon(Backgrounds.BG_MATCH, preferredDir + FILE_MATCH_BG); - - // Run through enums and load their coords. - for (final Colors e : Colors.values()) { FSkin.setColor(e); } - for (final ZoneImages e : ZoneImages.values()) { FSkin.setImage(e); } - for (final DockIcons e : DockIcons.values()) { FSkin.setIcon(e); } - for (final InterfaceIcons e : InterfaceIcons.values()) { FSkin.setIcon(e); } - for (final ButtonImages e : ButtonImages.values()) { FSkin.setIcon(e); } - for (final QuestIcons e : QuestIcons.values()) { FSkin.setIcon(e); } - - for (final EditorImages e : EditorImages.values()) { FSkin.setImage(e); } - for (final ManaImages e : ManaImages.values()) { FSkin.setImage(e); } - for (final ColorlessManaImages e : ColorlessManaImages.values()) { FSkin.setImage(e); } - for (final GameplayImages e : GameplayImages.values()) { FSkin.setImage(e); } - for (final LayoutImages e : LayoutImages.values()) { FSkin.setImage(e); } - - // Foils have a separate sprite, so uses a specific method. - for (final Foils e : Foils.values()) { FSkin.setFoil(e, false); } - for (final OldFoils e : OldFoils.values()) { FSkin.setFoil(e, true); } - - // Assemble avatar images - FSkin.assembleAvatars(); - - // Table zebra striping - UIManager.put("Table.alternateRowColor", new Color(240, 240, 240)); - - // Images loaded; can start UI init. - setProgessBarMessage("Creating display components."); - - // Clear references to buffered images - FSkin.bimDefaultSprite.flush(); - FSkin.bimFoils.flush(); - FSkin.bimOldFoils.flush(); - FSkin.bimPreferredSprite.flush(); - FSkin.bimDefaultAvatars.flush(); - - if (FSkin.bimPreferredAvatars != null) { FSkin.bimPreferredAvatars.flush(); } - - FSkin.bimDefaultSprite = null; - FSkin.bimFoils = null; - FSkin.bimOldFoils = null; - FSkin.bimPreferredSprite = null; - FSkin.bimDefaultAvatars = null; - FSkin.bimPreferredAvatars = null; - } - - /** @return {@link java.awt.font} font */ - public static Font getFont() { - return FSkin.font; - } - - /** - * @param size - integer, pixel size - * @return {@link java.awt.font} font1 - */ - public static Font getFont(final int size) { - if (plainFonts.get(size) == null) { - plainFonts.put(size, getFont().deriveFont(Font.PLAIN, size)); - } - return plainFonts.get(size); - } - - /** - * @param size - integer, pixel size - * @return {@link java.awt.font} font1 - */ - public static Font getBoldFont(final int size) { - if (boldFonts.get(size) == null) { - boldFonts.put(size, getFont().deriveFont(Font.BOLD, size)); - } - return boldFonts.get(size); - } - - /** - * @param size - integer, pixel size - * @return {@link java.awt.font} font1 - */ - public static Font getItalicFont(final int size) { - if (boldFonts.get(size) == null) { - italicFonts.put(size, getFont().deriveFont(Font.ITALIC, size)); - } - return italicFonts.get(size); - } - - /** - * Gets the name. - * - * @return Name of the current skin. - */ - public static String getName() { - return FSkin.preferredName; - } - - /** - * Gets an image. - * - * @param s0   SkinProp enum - * @return {@link java.awt.Image} - */ - public static Image getImage(final SkinProp s0) { - if (FSkin.images.get(s0) == null) { - throw new NullPointerException("Can't find an image for SkinProp " + s0); - } - return FSkin.images.get(s0); - } - - /** - * Gets an icon. - * - * @param s0   SkinProp enum - * @return {@link javax.swing.ImageIcon} - */ - public static ImageIcon getIcon(final SkinProp s0) { - if (FSkin.icons.get(s0) == null) { - throw new NullPointerException("Can't find an icon for SkinProp " + s0); - } - return FSkin.icons.get(s0); - } - - /** - * Gets a scaled version of an image from this skin's image map. - * - * @param s0 - * String image enum - * @param w0 - * int new width - * @param h0 - * int new height - * @return {@link java.awt.Image} - */ - public static Image getImage(final SkinProp s0, int w0, int h0) { - w0 = (w0 < 1) ? 1 : w0; - h0 = (h0 < 1) ? 1 : h0; - - final Image original = FSkin.images.get(s0); - - final BufferedImage scaled = new BufferedImage(w0, h0, BufferedImage.TYPE_INT_ARGB); - - final Graphics2D g2d = scaled.createGraphics(); - g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); - g2d.drawImage(original, 0, 0, w0, h0, 0, 0, original.getWidth(null), original.getHeight(null), null); - g2d.dispose(); - - return scaled; - } - - /** - * Retrieves a color from this skin's color map. - * - * @param s0   Skin property (from enum) - * @return Color - */ - public static Color getColor(final SkinProp s0) { - return colors.get(s0); - } - - /** - * Gets the skins. - * - * @return the skins - */ - public static ArrayList getSkins() { - final ArrayList mySkins = new ArrayList(); - - final File dir = new File(FILE_SKINS_DIR); - final String[] children = dir.list(); - if (children == null) { - System.err.println("FSkin > can't find skins directory!"); - } else { - for (int i = 0; i < children.length; i++) { - if (children[i].equalsIgnoreCase(".svn")) { continue; } - if (children[i].equalsIgnoreCase(".DS_Store")) { continue; } - mySkins.add(children[i]); - } - } - - return mySkins; - } - - /** @return Map */ - public static Map getAvatars() { - return avatars; - } - - /** Steps RGB components of a color up or down. - * Returns opaque (non-alpha) stepped color. - * Plus for lighter, minus for darker. - * - * @param clr0 {@link java.awt.Color} - * @param step int - * @return {@link java.awt.Color} - */ - public static Color stepColor(Color clr0, int step) { - int r = clr0.getRed(); - int g = clr0.getGreen(); - int b = clr0.getBlue(); - - // Darker - if (step < 0) { - r = ((r + step > 0) ? r + step : 0); - g = ((g + step > 0) ? g + step : 0); - b = ((b + step > 0) ? b + step : 0); - } - else { - r = ((r + step < 255) ? r + step : 255); - g = ((g + step < 255) ? g + step : 255); - b = ((b + step < 255) ? b + step : 255); - } - - return new Color(r, g, b); - } - - /** Returns RGB components of a color, with a new - * value for alpha. 0 = transparent, 255 = opaque. - * - * @param clr0 {@link java.awt.Color} - * @param alpha int - * @return {@link java.awt.Color} - */ - public static Color alphaColor(Color clr0, int alpha) { - return new Color(clr0.getRed(), clr0.getGreen(), clr0.getBlue(), alpha); - } - - /** - *

- * getColorFromPixel. - *

- * - * @param {@link java.lang.Integer} pixel information - */ - private static Color getColorFromPixel(final int pixel) { - int r, g, b, a; - a = (pixel >> 24) & 0x000000ff; - r = (pixel >> 16) & 0x000000ff; - g = (pixel >> 8) & 0x000000ff; - b = (pixel) & 0x000000ff; - return new Color(r, g, b, a); - } - - private static BufferedImage testPreferredSprite(final SkinProp s0) { - tempCoords = s0.getCoords(); - x0 = tempCoords[0]; - y0 = tempCoords[1]; - w0 = tempCoords[2]; - h0 = tempCoords[3]; - - // Test if requested sub-image in inside bounds of preferred sprite. - // (Height and width of preferred sprite were set in loadFontAndImages.) - if (x0 > preferredW || x0 + w0 > preferredW - || y0 > preferredH || y0 + h0 > preferredH) { - return bimDefaultSprite; - } - - // Test if various points of requested sub-image are transparent. - // If any return true, image exists. - int x = 0, y = 0; - Color c; - - // Center - x = (x0 + w0 / 2); - y = (y0 + h0 / 2); - c = FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x, y)); - if (c.getAlpha() != 0) { return bimPreferredSprite; } - - x += 2; - y += 2; - c = FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x, y)); - if (c.getAlpha() != 0) { return bimPreferredSprite; } - - x -= 4; - c = FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x, y)); - if (c.getAlpha() != 0) { return bimPreferredSprite; } - - y -= 4; - c = FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x, y)); - if (c.getAlpha() != 0) { return bimPreferredSprite; } - - x += 4; - c = FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x, y)); - if (c.getAlpha() != 0) { return bimPreferredSprite; } - - return bimDefaultSprite; - } - - private static void assembleAvatars() { - FSkin.avatars = new HashMap(); - int counter = 0; - Color pxTest; - - if (bimPreferredAvatars != null) { - final int pw = bimPreferredAvatars.getWidth(); - final int ph = bimPreferredAvatars.getHeight(); - - for (int j = 0; j < ph; j += 100) { - for (int i = 0; i < pw; i += 100) { - if (i == 0 && j == 0) { continue; } - pxTest = FSkin.getColorFromPixel(bimPreferredAvatars.getRGB(i + 50, j + 50)); - if (pxTest.getAlpha() == 0) { continue; } - FSkin.avatars.put(counter++, bimPreferredAvatars.getSubimage(i, j, 100, 100)); - } - } - } - - final int aw = bimDefaultAvatars.getWidth(); - final int ah = bimDefaultAvatars.getHeight(); - - for (int j = 0; j < ah; j += 100) { - for (int i = 0; i < aw; i += 100) { - if (i == 0 && j == 0) { continue; } - pxTest = FSkin.getColorFromPixel(bimDefaultAvatars.getRGB(i + 50, j + 50)); - if (pxTest.getAlpha() == 0) { continue; } - FSkin.avatars.put(counter++, bimDefaultAvatars.getSubimage(i, j, 100, 100)); - } - } - } - - private static void setFoil(final SkinProp s0, boolean isOldStyle) { - tempCoords = s0.getCoords(); - x0 = tempCoords[0]; - y0 = tempCoords[1]; - w0 = tempCoords[2]; - h0 = tempCoords[3]; - - FSkin.images.put(s0, isOldStyle ? bimOldFoils.getSubimage(x0, y0, w0, h0) : bimFoils.getSubimage(x0, y0, w0, h0)); - } - - private static void setColor(final SkinProp s0) { - tempCoords = s0.getCoords(); - x0 = tempCoords[0]; - y0 = tempCoords[1]; - - FSkin.colors.put(s0, FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x0, y0))); - } - - private static void setFont(final int size) { - plainFonts.put(size, font.deriveFont(Font.PLAIN, size)); - } - - private static void setBoldFont(final int size) { - boldFonts.put(size, font.deriveFont(Font.BOLD, size)); - } - - private static void setItalicFont(final int size) { - italicFonts.put(size, FSkin.font.deriveFont(Font.ITALIC, size)); - } - - private static void setIcon(final SkinProp s0) { - tempCoords = s0.getCoords(); - x0 = tempCoords[0]; - y0 = tempCoords[1]; - w0 = tempCoords[2]; - h0 = tempCoords[3]; - - final BufferedImage img = testPreferredSprite(s0); - - FSkin.icons.put(s0, new ImageIcon(img.getSubimage(x0, y0, w0, h0))); - } - - /** - * Sets an icon in this skin's icon map from a file address. - * Throws IO exception for debugging if needed. - * - * @param s0 - *   Skin property (from enum) - * @param s1 - *   File address - */ - private static void setIcon(final SkinProp s0, final String s1) { - try { - final File file = new File(s1); - ImageIO.read(file); - } catch (final IOException e) { - e.printStackTrace(); - } - FSkin.icons.put(s0, new ImageIcon(s1)); - } - - /** - * Sets an icon in this skin's icon map from a buffered image. - * - * @param s0   Skin property (from enum) - * @param bi0   BufferedImage - */ - private static void setIcon(final SkinProp s0, final BufferedImage bi0) { - FSkin.icons.put(s0, new ImageIcon(bi0)); - } - - /** - * setImage, with auto-scaling assumed true. - * - * @param s0 - */ - private static void setImage(final SkinProp s0) { - FSkin.setImage(s0, true); - } - - /** - * Checks the preferred sprite for existence of a sub-image - * defined by X, Y, W, H. - * - * If an image is not present at those coordinates, default - * icon is substituted. - * - * The result is saved in a HashMap. - * - * @param s0   An address in the hashmap, derived from SkinProp enum - */ - private static void setImage(final SkinProp s0, final boolean scale) { - tempCoords = s0.getCoords(); - x0 = tempCoords[0]; - y0 = tempCoords[1]; - w0 = tempCoords[2]; - h0 = tempCoords[3]; - newW = (tempCoords.length == 6 ? tempCoords[4] : 0); - newH = (tempCoords.length == 6 ? tempCoords[5] : 0); - - final BufferedImage img = FSkin.testPreferredSprite(s0); - final BufferedImage bi0 = img.getSubimage(x0, y0, w0, h0); - - if (scale && newW != 0) { - FSkin.images.put(s0, bi0.getScaledInstance(newW, newH, Image.SCALE_AREA_AVERAGING)); - } - else { - FSkin.images.put(s0, bi0); - } - } -} +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * +import forge.view.SplashFrame; + This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.toolbox; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.LineBorder; + +import org.apache.commons.lang.WordUtils; + +import forge.FThreads; +import forge.gui.GuiUtils; +import forge.view.FView; + +/** + * Assembles settings from selected or default theme as appropriate. Saves in a + * hashtable, access using .get(settingName) method. + * + */ + +public enum FSkin { + /** Singleton instance of skin. */ + SINGLETON_INSTANCE; + + /** */ + public enum Backgrounds implements SkinProp { /** */ + BG_SPLASH (null), /** */ + BG_TEXTURE (null), /** */ + BG_MATCH (null); /** */ + + private int[] coords; + /** @param xy   int[] coordinates */ + Backgrounds(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** */ + public enum Colors implements SkinProp { /** */ + CLR_THEME (new int[] {70, 10}), /** */ + CLR_BORDERS (new int[] {70, 30}), /** */ + CLR_ZEBRA (new int[] {70, 50}), /** */ + CLR_HOVER (new int[] {70, 70}), /** */ + CLR_ACTIVE (new int[] {70, 90}), /** */ + CLR_INACTIVE (new int[] {70, 110}), /** */ + CLR_TEXT (new int[] {70, 130}), /** */ + CLR_PHASE_INACTIVE_ENABLED (new int[] {70, 150}), /** */ + CLR_PHASE_INACTIVE_DISABLED (new int[] {70, 170}), /** */ + CLR_PHASE_ACTIVE_ENABLED (new int[] {70, 190}), /** */ + CLR_PHASE_ACTIVE_DISABLED (new int[] {70, 210}), /** */ + CLR_THEME2 (new int[] {70, 230}), /** */ + CLR_OVERLAY (new int[] {70, 250}); + + private int[] coords; + /** @param xy   int[] coordinates */ + Colors(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** int[] can hold [xcoord, ycoord, width, height, newwidth, newheight]. */ + public enum ZoneImages implements SkinProp { /** */ + ICO_HAND (new int[] {280, 40, 40, 40}), /** */ + ICO_LIBRARY (new int[] {280, 0, 40, 40}), /** */ + ICO_EXILE (new int[] {320, 40, 40, 40}), /** */ + ICO_FLASHBACK (new int[] {280, 80, 40, 40}), /** */ + ICO_GRAVEYARD (new int[] {320, 0, 40, 40}), /** */ + ICO_POISON (new int[] {320, 80, 40, 40}); + + private int[] coords; + /** @param xy   int[] coordinates */ + ZoneImages(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** int[] can hold [xcoord, ycoord, width, height, newwidth, newheight]. */ + public enum ManaImages implements SkinProp { /** */ + IMG_BLACK (new int[] {360, 160, 40, 40}), /** */ + IMG_RED (new int[] {400, 160, 40, 40}), /** */ + IMG_COLORLESS (new int[] {440, 160, 40, 40}), /** */ + IMG_BLUE (new int[] {360, 200, 40, 40}), /** */ + IMG_GREEN (new int[] {400, 200, 40, 40}), /** */ + IMG_WHITE (new int[] {440, 200, 40, 40}), /** */ + IMG_2B (new int[] {360, 400, 40, 40}), /** */ + IMG_2G (new int[] {400, 400, 40, 40}), /** */ + IMG_2R (new int[] {440, 400, 40, 40}), /** */ + IMG_2U (new int[] {440, 360, 40, 40}), /** */ + IMG_2W (new int[] {400, 360, 40, 40}), /** */ + IMG_BLACK_GREEN (new int[] {360, 240, 40, 40}), /** */ + IMG_BLACK_RED (new int[] {400, 240, 40, 40}), /** */ + IMG_GREEN_BLUE (new int[] {360, 280, 40, 40}), /** */ + IMG_GREEN_WHITE (new int[] {440, 280, 40, 40}), /** */ + IMG_RED_GREEN (new int[] {360, 320, 40, 40}), /** */ + IMG_RED_WHITE (new int[] {400, 320, 40, 40}), /** */ + IMG_BLUE_BLACK (new int[] {440, 240, 40, 40}), /** */ + IMG_BLUE_RED (new int[] {440, 320, 40, 40}), /** */ + IMG_WHITE_BLACK (new int[] {400, 280, 40, 40}), /** */ + IMG_WHITE_BLUE (new int[] {360, 360, 40, 40}), /** */ + IMG_PHRYX_BLUE (new int[] {320, 200, 40, 40}), /** */ + IMG_PHRYX_WHITE (new int[] {320, 240, 40, 40}), /** */ + IMG_PHRYX_RED (new int[] {320, 280, 40, 40}), /** */ + IMG_PHRYX_GREEN (new int[] {320, 320, 40, 40}), /** */ + IMG_PHRYX_BLACK (new int[] {320, 360, 40, 40}); + + private int[] coords; + /** @param xy   int[] coordinates */ + ManaImages(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** int[] can hold [xcoord, ycoord, width, height, newwidth, newheight]. */ + public enum ColorlessManaImages implements SkinProp { /** */ + IMG_0 (new int[] {640, 200, 20, 20}), /** */ + IMG_1 (new int[] {660, 200, 20, 20}), /** */ + IMG_2 (new int[] {640, 220, 20, 20}), /** */ + IMG_3 (new int[] {660, 220, 20, 20}), /** */ + IMG_4 (new int[] {640, 240, 20, 20}), /** */ + IMG_5 (new int[] {660, 240, 20, 20}), /** */ + IMG_6 (new int[] {640, 260, 20, 20}), /** */ + IMG_7 (new int[] {660, 260, 20, 20}), /** */ + IMG_8 (new int[] {640, 280, 20, 20}), /** */ + IMG_9 (new int[] {660, 280, 20, 20}), /** */ + IMG_10 (new int[] {640, 300, 20, 20}), /** */ + IMG_11 (new int[] {660, 300, 20, 20}), /** */ + IMG_12 (new int[] {640, 320, 20, 20}), /** */ + IMG_15 (new int[] {660, 340, 20, 20}), /** */ + IMG_16 (new int[] {640, 360, 20, 20}), /** */ + IMG_20 (new int[] {640, 400, 20, 20}), /** */ + IMG_X (new int[] {640, 420, 20, 20}), /** */ + IMG_Y (new int[] {660, 420, 20, 20}), /** */ + IMG_Z (new int[] {640, 440, 20, 20}); + + private int[] coords; + /** @param xy   int[] coordinates */ + ColorlessManaImages(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** int[] can hold [xcoord, ycoord, width, height, newwidth, newheight]. */ + public enum GameplayImages implements SkinProp { /** */ + IMG_SNOW (new int[] {320, 160, 40, 40}), /** */ + IMG_TAP (new int[] {660, 440, 20, 20}), /** */ + IMG_UNTAP (new int[] {640, 460, 20, 20}), /** */ + IMG_SLASH (new int[] {660, 400, 10, 13}), /** */ + IMG_ATTACK (new int[] {160, 320, 80, 80, 32, 32}), /** */ + IMG_DEFEND (new int[] {160, 400, 80, 80, 32, 32}), /** */ + IMG_SUMMONSICK (new int[] {240, 400, 80, 80, 32, 32}), /** */ + IMG_PHASING (new int[] {240, 320, 80, 80, 32, 32}), /** */ + IMG_COSTRESERVED (new int[] {240, 240, 80, 80, 40, 40}), /** */ + IMG_COUNTERS1 (new int[] {0, 320, 80, 80}), /** */ + IMG_COUNTERS2 (new int[] {0, 400, 80, 80}), /** */ + IMG_COUNTERS3 (new int[] {80, 320, 80, 80}), /** */ + IMG_COUNTERS_MULTI (new int[] {80, 400, 80, 80}); + + private int[] coords; + /** @param xy   int[] coordinates */ + GameplayImages(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** */ + public enum Foils implements SkinProp { /** */ + FOIL_01 (new int[] {0, 0, 400, 570}), /** */ + FOIL_02 (new int[] {400, 0, 400, 570}), /** */ + FOIL_03 (new int[] {0, 570, 400, 570}), /** */ + FOIL_04 (new int[] {400, 570, 400, 570}), /** */ + FOIL_05 (new int[] {0, 1140, 400, 570}), /** */ + FOIL_06 (new int[] {400, 1140, 400, 570}), /** */ + FOIL_07 (new int[] {0, 1710, 400, 570}), /** */ + FOIL_08 (new int[] {400, 1710, 400, 570}), /** */ + FOIL_09 (new int[] {0, 2280, 400, 570}), /** */ + FOIL_10 (new int[] {400, 2280, 400, 570}); /** */ + + private int[] coords; + /** @param xy   int[] coordinates */ + Foils(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + public enum OldFoils implements SkinProp { /** */ + FOIL_11 (new int[] {0, 0, 400, 570}), /** */ + FOIL_12 (new int[] {400, 0, 400, 570}), /** */ + FOIL_13 (new int[] {0, 570, 400, 570}), /** */ + FOIL_14 (new int[] {400, 570, 400, 570}), /** */ + FOIL_15 (new int[] {0, 1140, 400, 570}), /** */ + FOIL_16 (new int[] {400, 1140, 400, 570}), /** */ + FOIL_17 (new int[] {0, 1710, 400, 570}), /** */ + FOIL_18 (new int[] {400, 1710, 400, 570}), /** */ + FOIL_19 (new int[] {0, 2280, 400, 570}), /** */ + FOIL_20 (new int[] {400, 2280, 400, 570}); /** */ + + private int[] coords; + /** @param xy   int[] coordinates */ + OldFoils(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** */ + public enum DockIcons implements SkinProp { /** */ + ICO_SHORTCUTS (new int[] {160, 640, 80, 80}), /** */ + ICO_SETTINGS (new int[] {80, 640, 80, 80}), /** */ + ICO_ENDTURN (new int[] {320, 640, 80, 80}), /** */ + ICO_CONCEDE (new int[] {240, 640, 80, 80}), /** */ + ICO_REVERTLAYOUT (new int[] {400, 720, 80, 80}), /** */ + ICO_OPENLAYOUT (new int[] {0, 800, 80, 80}), /** */ + ICO_SAVELAYOUT (new int[] {80, 800, 80, 80}), /** */ + ICO_DECKLIST (new int[] {400, 640, 80, 80}), /** */ + ICO_ALPHASTRIKE (new int[] {160, 800, 80, 80}), /** */ + ICO_ARCSOFF (new int[] {240, 800, 80, 80}), /** */ + ICO_ARCSON (new int[] {320, 800, 80, 80}), /** */ + ICO_ARCSHOVER (new int[] {400, 800, 80, 80}); + + private int[] coords; + /** @param xy   int[] coordinates */ + DockIcons(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** */ + public enum QuestIcons implements SkinProp { /** */ + ICO_ZEP (new int[] {0, 480, 80, 80}), /** */ + ICO_GEAR (new int[] {80, 480, 80, 80}), /** */ + ICO_GOLD (new int[] {160, 480, 80, 80}), /** */ + ICO_ELIXIR (new int[] {240, 480, 80, 80}), /** */ + ICO_BOOK (new int[] {320, 480, 80, 80}), /** */ + ICO_BOTTLES (new int[] {400, 480, 80, 80}), /** */ + ICO_BOX (new int[] {480, 480, 80, 80}), /** */ + ICO_COIN (new int[] {560, 480, 80, 80}), /** */ + + ICO_FOX (new int[] {0, 560, 80, 80}), /** */ + ICO_LEAF (new int[] {80, 560, 80, 80}), /** */ + ICO_LIFE (new int[] {160, 560, 80, 80}), /** */ + ICO_COINSTACK (new int[] {240, 560, 80, 80}), /** */ + ICO_MAP (new int[] {320, 560, 80, 80}), /** */ + ICO_NOTES (new int[] {400, 560, 80, 80}), /** */ + ICO_HEART (new int[] {480, 560, 80, 80}), /** */ + ICO_BREW (new int[] {560, 560, 80, 80}), /** */ + + ICO_MINUS (new int[] {560, 640, 80, 80}), /** */ + ICO_PLUS (new int[] {480, 640, 80, 80}), /** */ + ICO_PLUSPLUS (new int[] {480, 720, 80, 80}); + + private int[] coords; + /** @param xy   int[] coordinates */ + QuestIcons(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** */ + public enum InterfaceIcons implements SkinProp { /** */ + ICO_DELETE (new int[] {640, 480, 20, 20}), /** */ + ICO_DELETE_OVER (new int[] {660, 480, 20, 20}), /** */ + ICO_EDIT (new int[] {640, 500, 20, 20}), /** */ + ICO_EDIT_OVER (new int[] {660, 500, 20, 20}), /** */ + ICO_OPEN (new int[] {660, 520, 20, 20}), /** */ + ICO_MINUS (new int[] {660, 620, 20, 20}), /** */ + ICO_NEW (new int[] {660, 540, 20, 20}), /** */ + ICO_PLUS (new int[] {660, 600, 20, 20}), /** */ + ICO_PRINT (new int[] {660, 640, 20, 20}), /** */ + ICO_SAVE (new int[] {660, 560, 20, 20}), /** */ + ICO_SAVEAS (new int[] {660, 580, 20, 20}), /** */ + ICO_UNKNOWN (new int[] {0, 720, 80, 80}), /** */ + ICO_LOGO (new int[] {480, 0, 200, 200}), /** */ + ICO_FLIPCARD (new int[] {400, 0, 80, 120}), /** */ + ICO_FAVICON (new int[] {0, 640, 80, 80}); + + private int[] coords; + /** @param xy   int[] coordinates */ + InterfaceIcons(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** */ + public enum LayoutImages implements SkinProp { /** */ + IMG_HANDLE (new int[] {320, 450, 80, 20}), /** */ + IMG_CUR_L (new int[] {564, 724, 32, 32}), /** */ + IMG_CUR_R (new int[] {564, 764, 32, 32}), /** */ + IMG_CUR_T (new int[] {604, 724, 32, 32}), /** */ + IMG_CUR_B (new int[] {604, 764, 32, 32}), /** */ + IMG_CUR_TAB (new int[] {644, 764, 32, 32}); + + private int[] coords; + /** @param xy   int[] coordinates */ + LayoutImages(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** */ + public enum EditorImages implements SkinProp { /** */ + IMG_ARTIFACT (new int[] {280, 720, 40, 40}), /** */ + IMG_CREATURE (new int[] {240, 720, 40, 40}), /** */ + IMG_ENCHANTMENT (new int[] {320, 720, 40, 40}), /** */ + IMG_INSTANT (new int[] {360, 720, 40, 40}), /** */ + IMG_LAND (new int[] {120, 720, 40, 40}), /** */ + IMG_MULTI (new int[] {80, 720, 40, 40}), /** */ + IMG_PLANESWALKER (new int[] {200, 720, 40, 40}), /** */ + IMG_PACK (new int[] {80, 760, 40, 40}), /** */ + IMG_SORCERY (new int[] {160, 720, 40, 40}); + + private int[] coords; + /** @param xy   int[] coordinates */ + EditorImages(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** */ + public enum ButtonImages implements SkinProp { /** */ + IMG_BTN_START_UP (new int[] {480, 200, 160, 80}), /** */ + IMG_BTN_START_OVER (new int[] {480, 280, 160, 80}), /** */ + IMG_BTN_START_DOWN (new int[] {480, 360, 160, 80}), /** */ + + IMG_BTN_UP_LEFT (new int[] {80, 0, 40, 40}), /** */ + IMG_BTN_UP_CENTER (new int[] {120, 0, 1, 40}), /** */ + IMG_BTN_UP_RIGHT (new int[] {160, 0, 40, 40}), /** */ + + IMG_BTN_OVER_LEFT (new int[] {80, 40, 40, 40}), /** */ + IMG_BTN_OVER_CENTER (new int[] {120, 40, 1, 40}), /** */ + IMG_BTN_OVER_RIGHT (new int[] {160, 40, 40, 40}), /** */ + + IMG_BTN_DOWN_LEFT (new int[] {80, 80, 40, 40}), /** */ + IMG_BTN_DOWN_CENTER (new int[] {120, 80, 1, 40}), /** */ + IMG_BTN_DOWN_RIGHT (new int[] {160, 80, 40, 40}), /** */ + + IMG_BTN_FOCUS_LEFT (new int[] {80, 120, 40, 40}), /** */ + IMG_BTN_FOCUS_CENTER (new int[] {120, 120, 1, 40}), /** */ + IMG_BTN_FOCUS_RIGHT (new int[] {160, 120, 40, 40}), /** */ + + IMG_BTN_TOGGLE_LEFT (new int[] {80, 160, 40, 40}), /** */ + IMG_BTN_TOGGLE_CENTER (new int[] {120, 160, 1, 40}), /** */ + IMG_BTN_TOGGLE_RIGHT (new int[] {160, 160, 40, 40}), /** */ + + IMG_BTN_DISABLED_LEFT (new int[] {80, 200, 40, 40}), /** */ + IMG_BTN_DISABLED_CENTER (new int[] {120, 200, 1, 40}), /** */ + IMG_BTN_DISABLED_RIGHT (new int[] {160, 200, 40, 40}); + + private int[] coords; + /** @param xy   int[] coordinates */ + ButtonImages(final int[] xy) { this.coords = xy; } + /** @return int[] */ + @Override + public int[] getCoords() { return coords; } + } + + /** Properties of various components that make up the skin. + * This interface allows all enums to be under the same roof. + * It also enforces a getter for coordinate locations in sprites. */ + public interface SkinProp { + /** @return int[] */ + int[] getCoords(); + } + + private static Map icons; + private static Map images; + private static Map colors; + + private static Map plainFonts; + private static Map boldFonts; + private static Map italicFonts; + private static Map avatars; + + private static final String + FILE_SKINS_DIR = "res/skins/", + FILE_ICON_SPRITE = "sprite_icons.png", + FILE_FOIL_SPRITE = "sprite_foils.png", + FILE_OLD_FOIL_SPRITE = "sprite_old_foils.png", + FILE_AVATAR_SPRITE = "sprite_avatars.png", + FILE_FONT = "font1.ttf", + FILE_SPLASH = "bg_splash.png", + FILE_MATCH_BG = "bg_match.jpg", + FILE_TEXTURE_BG = "bg_texture.jpg", + DEFAULT_DIR = FILE_SKINS_DIR + "default/"; + + private static String preferredDir; + private static String preferredName; + private static Font font; + private static BufferedImage bimDefaultSprite, bimPreferredSprite, bimFoils, + bimOldFoils, bimDefaultAvatars, bimPreferredAvatars; + private static int x0, y0, w0, h0, newW, newH, preferredW, preferredH; + private static int[] tempCoords; + + /** + * Loads a "light" version of FSkin, just enough for the splash screen: + * skin name. Generates custom skin settings, fonts, and backgrounds. + * + * + * @param skinName + * the skin name + */ + public static void loadLight(final String skinName) { + // No need for this method to be loaded while on the EDT. + FThreads.assertExecutedByEdt(false); + + // Non-default (preferred) skin name and dir. + FSkin.preferredName = skinName.toLowerCase().replace(' ', '_'); + FSkin.preferredDir = FILE_SKINS_DIR + preferredName + "/"; + + if (FSkin.icons != null) { FSkin.icons.clear(); } + if (FSkin.images != null) { FSkin.images.clear(); } + if (FSkin.colors != null) { FSkin.colors.clear(); } + + FSkin.icons = new HashMap(); + FSkin.images = new HashMap(); + FSkin.colors = new HashMap(); + + final File f = new File(preferredDir + FILE_SPLASH); + if (!f.exists()) { + FSkin.loadLight("default"); + } + else { + final BufferedImage img; + try { + img = ImageIO.read(f); + + final int h = img.getHeight(); + final int w = img.getWidth(); + + FSkin.setIcon(Backgrounds.BG_SPLASH, img.getSubimage(0, 0, w, h - 100)); + + UIManager.put("ProgressBar.background", FSkin.getColorFromPixel(img.getRGB(25, h - 75))); + UIManager.put("ProgressBar.selectionBackground", FSkin.getColorFromPixel(img.getRGB(75, h - 75))); + UIManager.put("ProgressBar.foreground", FSkin.getColorFromPixel(img.getRGB(25, h - 25))); + UIManager.put("ProgressBar.selectionForeground", FSkin.getColorFromPixel(img.getRGB(75, h - 25))); + UIManager.put("ProgressBar.border", new LineBorder(Color.BLACK, 0)); + } catch (final IOException e) { + e.printStackTrace(); + } + } + } + + public static void setProgessBarMessage(final String message) { + setProgessBarMessage(message, 0); + } + public static void setProgessBarMessage(final String message, final int cnt) { + final FProgressBar barProgress = FView.SINGLETON_INSTANCE.getSplash().getProgressBar(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if ( cnt > 0 ) { + barProgress.reset(); + barProgress.setMaximum(cnt); + } + barProgress.setShowETA(false); + barProgress.setShowCount(cnt > 0); + barProgress.setDescription(message); + + } + }); + } + + /** + * Loads two sprites: the default (which should be a complete + * collection of all symbols) and the preferred (which may be + * incomplete). + * + * Font must be present in the skin folder, and will not + * be replaced by default. The fonts are pre-derived + * in this method and saved in a HashMap for future access. + * + * Color swatches must be present in the preferred + * sprite, and will not be replaced by default. + * + * Background images must be present in skin folder, + * and will not be replaced by default. + * + * Icons, however, will be pulled from the two sprites. Obviously, + * preferred takes precedence over default, but if something is + * missing, the default picture is retrieved. + */ + public static void loadFull() { + // No need for this method to be loaded while on the EDT. + FThreads.assertExecutedByEdt(false); + + // Preferred skin name must be called via loadLight() method, + // which does some cleanup and init work. + if (FSkin.preferredName.isEmpty()) { FSkin.loadLight("default"); } + + // Everything OK? + + final FProgressBar barProgress = FView.SINGLETON_INSTANCE.getSplash().getProgressBar(); + setProgessBarMessage("Processing image sprites: ", 5); + + + // Grab and test various sprite files. + final File f1 = new File(DEFAULT_DIR + FILE_ICON_SPRITE); + final File f2 = new File(preferredDir + FILE_ICON_SPRITE); + final File f3 = new File(DEFAULT_DIR + FILE_FOIL_SPRITE); + final File f4 = new File(DEFAULT_DIR + FILE_AVATAR_SPRITE); + final File f5 = new File(preferredDir + FILE_AVATAR_SPRITE); + final File f6 = new File(DEFAULT_DIR + FILE_OLD_FOIL_SPRITE); + + try { + bimDefaultSprite = ImageIO.read(f1); + barProgress.increment(); + bimPreferredSprite = ImageIO.read(f2); + barProgress.increment(); + bimFoils = ImageIO.read(f3); + barProgress.increment(); + bimOldFoils = f6.exists() ? ImageIO.read(f6) : ImageIO.read(f3); + barProgress.increment(); + bimDefaultAvatars = ImageIO.read(f4); + + if (f5.exists()) { bimPreferredAvatars = ImageIO.read(f5); } + + barProgress.increment(); + + preferredH = bimPreferredSprite.getHeight(); + preferredW = bimPreferredSprite.getWidth(); + } + catch (final Exception e) { + System.err.println("FSkin$loadFull: Missing a sprite (default icons, " + + "preferred icons, or foils."); + e.printStackTrace(); + } + + // Pre-derive most fonts (plain, bold, and italic). + // Exceptions handled inside method. + FSkin.font = GuiUtils.newFont(FILE_SKINS_DIR + preferredName + "/" + FILE_FONT); + plainFonts = new HashMap(); + boldFonts = new HashMap(); + italicFonts = new HashMap(); + for (int i = 10; i <= 22; i++) { setFont(i); } + for (int i = 10; i <= 20; i += 2) { setBoldFont(i); } + for (int i = 12; i <= 14; i += 2) { setItalicFont(i); } + + // Put various images into map (except sprite and splash). + // Exceptions handled inside method. + FSkin.setIcon(Backgrounds.BG_TEXTURE, preferredDir + FILE_TEXTURE_BG); + FSkin.setIcon(Backgrounds.BG_MATCH, preferredDir + FILE_MATCH_BG); + + // Run through enums and load their coords. + for (final Colors e : Colors.values()) { FSkin.setColor(e); } + for (final ZoneImages e : ZoneImages.values()) { FSkin.setImage(e); } + for (final DockIcons e : DockIcons.values()) { FSkin.setIcon(e); } + for (final InterfaceIcons e : InterfaceIcons.values()) { FSkin.setIcon(e); } + for (final ButtonImages e : ButtonImages.values()) { FSkin.setIcon(e); } + for (final QuestIcons e : QuestIcons.values()) { FSkin.setIcon(e); } + + for (final EditorImages e : EditorImages.values()) { FSkin.setImage(e); } + for (final ManaImages e : ManaImages.values()) { FSkin.setImage(e); } + for (final ColorlessManaImages e : ColorlessManaImages.values()) { FSkin.setImage(e); } + for (final GameplayImages e : GameplayImages.values()) { FSkin.setImage(e); } + for (final LayoutImages e : LayoutImages.values()) { FSkin.setImage(e); } + + // Foils have a separate sprite, so uses a specific method. + for (final Foils e : Foils.values()) { FSkin.setFoil(e, false); } + for (final OldFoils e : OldFoils.values()) { FSkin.setFoil(e, true); } + + // Assemble avatar images + FSkin.assembleAvatars(); + + // Table zebra striping + UIManager.put("Table.alternateRowColor", new Color(240, 240, 240)); + + // Images loaded; can start UI init. + setProgessBarMessage("Creating display components."); + + // Clear references to buffered images + FSkin.bimDefaultSprite.flush(); + FSkin.bimFoils.flush(); + FSkin.bimOldFoils.flush(); + FSkin.bimPreferredSprite.flush(); + FSkin.bimDefaultAvatars.flush(); + + if (FSkin.bimPreferredAvatars != null) { FSkin.bimPreferredAvatars.flush(); } + + FSkin.bimDefaultSprite = null; + FSkin.bimFoils = null; + FSkin.bimOldFoils = null; + FSkin.bimPreferredSprite = null; + FSkin.bimDefaultAvatars = null; + FSkin.bimPreferredAvatars = null; + } + + /** @return {@link java.awt.font} font */ + public static Font getFont() { + return FSkin.font; + } + + /** + * @param size - integer, pixel size + * @return {@link java.awt.font} font1 + */ + public static Font getFont(final int size) { + if (plainFonts.get(size) == null) { + plainFonts.put(size, getFont().deriveFont(Font.PLAIN, size)); + } + return plainFonts.get(size); + } + + /** + * @param size - integer, pixel size + * @return {@link java.awt.font} font1 + */ + public static Font getBoldFont(final int size) { + if (boldFonts.get(size) == null) { + boldFonts.put(size, getFont().deriveFont(Font.BOLD, size)); + } + return boldFonts.get(size); + } + + /** + * @param size - integer, pixel size + * @return {@link java.awt.font} font1 + */ + public static Font getItalicFont(final int size) { + if (boldFonts.get(size) == null) { + italicFonts.put(size, getFont().deriveFont(Font.ITALIC, size)); + } + return italicFonts.get(size); + } + + /** + * Gets the name. + * + * @return Name of the current skin. + */ + public static String getName() { + return FSkin.preferredName; + } + + /** + * Gets an image. + * + * @param s0   SkinProp enum + * @return {@link java.awt.Image} + */ + public static Image getImage(final SkinProp s0) { + if (FSkin.images.get(s0) == null) { + throw new NullPointerException("Can't find an image for SkinProp " + s0); + } + return FSkin.images.get(s0); + } + + /** + * Gets an icon. + * + * @param s0   SkinProp enum + * @return {@link javax.swing.ImageIcon} + */ + public static ImageIcon getIcon(final SkinProp s0) { + if (FSkin.icons.get(s0) == null) { + throw new NullPointerException("Can't find an icon for SkinProp " + s0); + } + return FSkin.icons.get(s0); + } + + /** + * Gets a scaled version of an image from this skin's image map. + * + * @param s0 + * String image enum + * @param w0 + * int new width + * @param h0 + * int new height + * @return {@link java.awt.Image} + */ + public static Image getImage(final SkinProp s0, int w0, int h0) { + w0 = (w0 < 1) ? 1 : w0; + h0 = (h0 < 1) ? 1 : h0; + + final Image original = FSkin.images.get(s0); + + final BufferedImage scaled = new BufferedImage(w0, h0, BufferedImage.TYPE_INT_ARGB); + + final Graphics2D g2d = scaled.createGraphics(); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g2d.drawImage(original, 0, 0, w0, h0, 0, 0, original.getWidth(null), original.getHeight(null), null); + g2d.dispose(); + + return scaled; + } + + /** + * Retrieves a color from this skin's color map. + * + * @param s0   Skin property (from enum) + * @return Color + */ + public static Color getColor(final SkinProp s0) { + return colors.get(s0); + } + + /** + * Gets the skins. + * + * @return the skins + */ + public static ArrayList getSkinDirectoryNames() { + final ArrayList mySkins = new ArrayList(); + + final File dir = new File(FILE_SKINS_DIR); + final String[] children = dir.list(); + if (children == null) { + System.err.println("FSkin > can't find skins directory!"); + } else { + for (int i = 0; i < children.length; i++) { + if (children[i].equalsIgnoreCase(".svn")) { continue; } + if (children[i].equalsIgnoreCase(".DS_Store")) { continue; } + mySkins.add(children[i]); + } + } + + return mySkins; + } + + public static String[] getSkinNamesArray() { + ArrayList skinDirectoryNames = getSkinDirectoryNames(); + String[] prettySkinNames = new String[skinDirectoryNames.size()]; + for (int i = 0; i < skinDirectoryNames.size(); i++) { + prettySkinNames[i] = WordUtils.capitalize(skinDirectoryNames.get(i).replace('_', ' ')); + } + return prettySkinNames; + } + + /** @return Map */ + public static Map getAvatars() { + return avatars; + } + + /** Steps RGB components of a color up or down. + * Returns opaque (non-alpha) stepped color. + * Plus for lighter, minus for darker. + * + * @param clr0 {@link java.awt.Color} + * @param step int + * @return {@link java.awt.Color} + */ + public static Color stepColor(Color clr0, int step) { + int r = clr0.getRed(); + int g = clr0.getGreen(); + int b = clr0.getBlue(); + + // Darker + if (step < 0) { + r = ((r + step > 0) ? r + step : 0); + g = ((g + step > 0) ? g + step : 0); + b = ((b + step > 0) ? b + step : 0); + } + else { + r = ((r + step < 255) ? r + step : 255); + g = ((g + step < 255) ? g + step : 255); + b = ((b + step < 255) ? b + step : 255); + } + + return new Color(r, g, b); + } + + /** Returns RGB components of a color, with a new + * value for alpha. 0 = transparent, 255 = opaque. + * + * @param clr0 {@link java.awt.Color} + * @param alpha int + * @return {@link java.awt.Color} + */ + public static Color alphaColor(Color clr0, int alpha) { + return new Color(clr0.getRed(), clr0.getGreen(), clr0.getBlue(), alpha); + } + + /** + *

+ * getColorFromPixel. + *

+ * + * @param {@link java.lang.Integer} pixel information + */ + private static Color getColorFromPixel(final int pixel) { + int r, g, b, a; + a = (pixel >> 24) & 0x000000ff; + r = (pixel >> 16) & 0x000000ff; + g = (pixel >> 8) & 0x000000ff; + b = (pixel) & 0x000000ff; + return new Color(r, g, b, a); + } + + private static BufferedImage testPreferredSprite(final SkinProp s0) { + tempCoords = s0.getCoords(); + x0 = tempCoords[0]; + y0 = tempCoords[1]; + w0 = tempCoords[2]; + h0 = tempCoords[3]; + + // Test if requested sub-image in inside bounds of preferred sprite. + // (Height and width of preferred sprite were set in loadFontAndImages.) + if (x0 > preferredW || x0 + w0 > preferredW + || y0 > preferredH || y0 + h0 > preferredH) { + return bimDefaultSprite; + } + + // Test if various points of requested sub-image are transparent. + // If any return true, image exists. + int x = 0, y = 0; + Color c; + + // Center + x = (x0 + w0 / 2); + y = (y0 + h0 / 2); + c = FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x, y)); + if (c.getAlpha() != 0) { return bimPreferredSprite; } + + x += 2; + y += 2; + c = FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x, y)); + if (c.getAlpha() != 0) { return bimPreferredSprite; } + + x -= 4; + c = FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x, y)); + if (c.getAlpha() != 0) { return bimPreferredSprite; } + + y -= 4; + c = FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x, y)); + if (c.getAlpha() != 0) { return bimPreferredSprite; } + + x += 4; + c = FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x, y)); + if (c.getAlpha() != 0) { return bimPreferredSprite; } + + return bimDefaultSprite; + } + + private static void assembleAvatars() { + FSkin.avatars = new HashMap(); + int counter = 0; + Color pxTest; + + if (bimPreferredAvatars != null) { + final int pw = bimPreferredAvatars.getWidth(); + final int ph = bimPreferredAvatars.getHeight(); + + for (int j = 0; j < ph; j += 100) { + for (int i = 0; i < pw; i += 100) { + if (i == 0 && j == 0) { continue; } + pxTest = FSkin.getColorFromPixel(bimPreferredAvatars.getRGB(i + 50, j + 50)); + if (pxTest.getAlpha() == 0) { continue; } + FSkin.avatars.put(counter++, bimPreferredAvatars.getSubimage(i, j, 100, 100)); + } + } + } + + final int aw = bimDefaultAvatars.getWidth(); + final int ah = bimDefaultAvatars.getHeight(); + + for (int j = 0; j < ah; j += 100) { + for (int i = 0; i < aw; i += 100) { + if (i == 0 && j == 0) { continue; } + pxTest = FSkin.getColorFromPixel(bimDefaultAvatars.getRGB(i + 50, j + 50)); + if (pxTest.getAlpha() == 0) { continue; } + FSkin.avatars.put(counter++, bimDefaultAvatars.getSubimage(i, j, 100, 100)); + } + } + } + + private static void setFoil(final SkinProp s0, boolean isOldStyle) { + tempCoords = s0.getCoords(); + x0 = tempCoords[0]; + y0 = tempCoords[1]; + w0 = tempCoords[2]; + h0 = tempCoords[3]; + + FSkin.images.put(s0, isOldStyle ? bimOldFoils.getSubimage(x0, y0, w0, h0) : bimFoils.getSubimage(x0, y0, w0, h0)); + } + + private static void setColor(final SkinProp s0) { + tempCoords = s0.getCoords(); + x0 = tempCoords[0]; + y0 = tempCoords[1]; + + FSkin.colors.put(s0, FSkin.getColorFromPixel(bimPreferredSprite.getRGB(x0, y0))); + } + + private static void setFont(final int size) { + plainFonts.put(size, font.deriveFont(Font.PLAIN, size)); + } + + private static void setBoldFont(final int size) { + boldFonts.put(size, font.deriveFont(Font.BOLD, size)); + } + + private static void setItalicFont(final int size) { + italicFonts.put(size, FSkin.font.deriveFont(Font.ITALIC, size)); + } + + private static void setIcon(final SkinProp s0) { + tempCoords = s0.getCoords(); + x0 = tempCoords[0]; + y0 = tempCoords[1]; + w0 = tempCoords[2]; + h0 = tempCoords[3]; + + final BufferedImage img = testPreferredSprite(s0); + + FSkin.icons.put(s0, new ImageIcon(img.getSubimage(x0, y0, w0, h0))); + } + + /** + * Sets an icon in this skin's icon map from a file address. + * Throws IO exception for debugging if needed. + * + * @param s0 + *   Skin property (from enum) + * @param s1 + *   File address + */ + private static void setIcon(final SkinProp s0, final String s1) { + try { + final File file = new File(s1); + ImageIO.read(file); + } catch (final IOException e) { + e.printStackTrace(); + } + FSkin.icons.put(s0, new ImageIcon(s1)); + } + + /** + * Sets an icon in this skin's icon map from a buffered image. + * + * @param s0   Skin property (from enum) + * @param bi0   BufferedImage + */ + private static void setIcon(final SkinProp s0, final BufferedImage bi0) { + FSkin.icons.put(s0, new ImageIcon(bi0)); + } + + /** + * setImage, with auto-scaling assumed true. + * + * @param s0 + */ + private static void setImage(final SkinProp s0) { + FSkin.setImage(s0, true); + } + + /** + * Checks the preferred sprite for existence of a sub-image + * defined by X, Y, W, H. + * + * If an image is not present at those coordinates, default + * icon is substituted. + * + * The result is saved in a HashMap. + * + * @param s0   An address in the hashmap, derived from SkinProp enum + */ + private static void setImage(final SkinProp s0, final boolean scale) { + tempCoords = s0.getCoords(); + x0 = tempCoords[0]; + y0 = tempCoords[1]; + w0 = tempCoords[2]; + h0 = tempCoords[3]; + newW = (tempCoords.length == 6 ? tempCoords[4] : 0); + newH = (tempCoords.length == 6 ? tempCoords[5] : 0); + + final BufferedImage img = FSkin.testPreferredSprite(s0); + final BufferedImage bi0 = img.getSubimage(x0, y0, w0, h0); + + if (scale && newW != 0) { + FSkin.images.put(s0, bi0.getScaledInstance(newW, newH, Image.SCALE_AREA_AVERAGING)); + } + else { + FSkin.images.put(s0, bi0); + } + } +}