From 42f4126aff07cbfa58e45d2abfb0dd2dba317b30 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Fri, 25 Oct 2019 15:37:13 +0800 Subject: [PATCH] Prepare Sleeve for Desktop... --- .../src/main/java/forge/GuiDesktop.java | 4 +- .../java/forge/screens/home/PlayerPanel.java | 110 +++++++++++++++++- .../main/java/forge/screens/home/VLobby.java | 17 +++ .../home/sanctioned/SleeveSelector.java | 71 +++++++++++ .../src/main/java/forge/toolbox/FSkin.java | 47 +++++++- 5 files changed, 246 insertions(+), 3 deletions(-) create mode 100644 forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/SleeveSelector.java diff --git a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java index 38f17b14647..b5cdb5b9f70 100644 --- a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java +++ b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java @@ -204,7 +204,9 @@ public class GuiDesktop implements IGuiBase { @Override public int getSleevesCount() { - //TODO + if (FSkin.isLoaded()) { + return FSkin.getSleeves().size(); + } return 0; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/PlayerPanel.java b/forge-gui-desktop/src/main/java/forge/screens/home/PlayerPanel.java index c6afcf7e625..dd1639b12ee 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/PlayerPanel.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/PlayerPanel.java @@ -14,6 +14,7 @@ import javax.swing.ButtonGroup; import javax.swing.JCheckBoxMenuItem; import javax.swing.JPopupMenu; +import forge.screens.home.sanctioned.SleeveSelector; import net.miginfocom.swing.MigLayout; import org.apache.commons.lang3.StringUtils; @@ -66,7 +67,8 @@ public class PlayerPanel extends FPanel { private final FLabel nameRandomiser; private final FLabel avatarLabel = new FLabel.Builder().opaque(true).hoverable(true).iconScaleFactor(0.99f).iconInBackground(true).build(); - private int avatarIndex; + private final FLabel sleeveLabel = new FLabel.Builder().opaque(true).hoverable(true).iconScaleFactor(0.99f).iconInBackground(true).build(); + private int avatarIndex, sleeveIndex; private final FTextField txtPlayerName = new FTextField.Builder().build(); private FRadioButton radioHuman; @@ -127,6 +129,10 @@ public class PlayerPanel extends FPanel { createAvatar(); this.add(avatarLabel, "spany 2, width 80px, height 80px"); + /*TODO Layout and Override for PC*/ + //createSleeve(); + //this.add(sleeveLabel, "spany 2, width 60px, height 80px"); + createNameEditor(); this.add(lobby.newLabel(localizer.getMessage("lblName") +":"), "w 40px, h 30px, gaptop 5px"); this.add(txtPlayerName, "h 30px, pushx, growx"); @@ -204,6 +210,10 @@ public class PlayerPanel extends FPanel { avatarLabel.setIcon(FSkin.getAvatars().get(Integer.valueOf(type == LobbySlotType.OPEN ? -1 : avatarIndex))); avatarLabel.repaintSelf(); + sleeveLabel.setEnabled(mayEdit); + sleeveLabel.setIcon(FSkin.getSleeves().get(Integer.valueOf(type == LobbySlotType.OPEN ? -1 : sleeveIndex))); + sleeveLabel.repaintSelf(); + txtPlayerName.setEnabled(mayEdit); txtPlayerName.setText(type == LobbySlotType.OPEN ? StringUtils.EMPTY : playerName); nameRandomiser.setEnabled(mayEdit); @@ -332,6 +342,62 @@ public class PlayerPanel extends FPanel { } }; + /** Listens to sleeve buttons and gives the appropriate player focus. */ + private final FocusAdapter sleeveFocusListener = new FocusAdapter() { + @Override + public void focusGained(final FocusEvent e) { + lobby.changePlayerFocus(index); + } + }; + + private final FMouseAdapter sleeveMouseListener = new FMouseAdapter() { + @Override public final void onLeftClick(final MouseEvent e) { + if (!sleeveLabel.isEnabled()) { + return; + } + + final FLabel sleeve = (FLabel)e.getSource(); + + lobby.changePlayerFocus(index); + sleeve.requestFocusInWindow(); + + final SleeveSelector sSel = new SleeveSelector(playerName, sleeveIndex, lobby.getUsedSleeves()); + for (final FLabel lbl : sSel.getSelectables()) { + lbl.setCommand(new UiCommand() { + @Override + public void run() { + setSleeveIndex(Integer.valueOf(lbl.getName().substring(11))); + sSel.setVisible(false); + } + }); + } + + sSel.setVisible(true); + sSel.dispose(); + + if (index < 2) { + lobby.updateSleevePrefs(); + } + + lobby.firePlayerChangeListener(index); + } + + @Override public final void onRightClick(final MouseEvent e) { + if (!sleeveLabel.isEnabled()) { + return; + } + + lobby.changePlayerFocus(index); + sleeveLabel.requestFocusInWindow(); + + setRandomSleeve(); + + if (index < 2) { + lobby.updateSleevePrefs(); + } + } + }; + private void updateVariantControlsVisibility() { final boolean isOathbreaker = lobby.hasVariant(GameType.Oathbreaker); final boolean isTinyLeaders = lobby.hasVariant(GameType.TinyLeaders); @@ -703,6 +769,20 @@ public class PlayerPanel extends FPanel { avatarLabel.addMouseListener(avatarMouseListener); } + private void createSleeve() { + final String[] currentPrefs = FModel.getPreferences().getPref(FPref.UI_SLEEVES).split(","); + if (index < currentPrefs.length) { + sleeveIndex = Integer.parseInt(currentPrefs[index]); + sleeveLabel.setIcon(FSkin.getSleeves().get(sleeveIndex)); + } else { + setRandomSleeve(false); + } + + sleeveLabel.setToolTipText("L-click: Select sleeve. R-click: Randomize sleeve."); + sleeveLabel.addFocusListener(sleeveFocusListener); + sleeveLabel.addMouseListener(sleeveMouseListener); + } + /** Applies a random avatar, avoiding avatars already used. */ private void setRandomAvatar() { setRandomAvatar(true); @@ -721,6 +801,24 @@ public class PlayerPanel extends FPanel { } } + /** Applies a random sleeve, avoiding sleeve already used. */ + private void setRandomSleeve() { + setRandomSleeve(true); + } + private void setRandomSleeve(final boolean fireListeners) { + int random = 0; + + final List usedSleeves = lobby.getUsedSleeves(); + do { + random = MyRandom.getRandom().nextInt(FSkin.getSleeves().size()); + } while (usedSleeves.contains(random)); + setSleeveIndex(random); + + if (fireListeners) { + lobby.firePlayerChangeListener(index); + } + } + private final FSkin.LineSkinBorder focusedBorder = new FSkin.LineSkinBorder(FSkin.getColor(FSkin.Colors.CLR_BORDERS).alphaColor(255), 3); private final FSkin.LineSkinBorder defaultBorder = new FSkin.LineSkinBorder(FSkin.getColor(FSkin.Colors.CLR_THEME).alphaColor(200), 2); @@ -746,6 +844,16 @@ public class PlayerPanel extends FPanel { avatarLabel.repaintSelf(); } + public int getSleeveIndex() { + return sleeveIndex; + } + public void setSleeveIndex(final int sleeveIndex0) { + sleeveIndex = sleeveIndex0; + final SkinImage icon = FSkin.getSleeves().get(sleeveIndex); + sleeveLabel.setIcon(icon); + sleeveLabel.repaintSelf(); + } + public int getTeam() { return teamComboBox.getSelectedIndex(); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java b/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java index 5be2e2a924b..5a58fa25598 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/VLobby.java @@ -858,6 +858,15 @@ public class VLobby implements ILobbyView { prefs.save(); } + /** Saves sleeve prefs for players one and two. */ + void updateSleevePrefs() { + final int pOneIndex = playerPanels.get(0).getSleeveIndex(); + final int pTwoIndex = playerPanels.get(1).getSleeveIndex(); + + prefs.setPref(FPref.UI_SLEEVES, pOneIndex + "," + pTwoIndex); + prefs.save(); + } + /** Adds a pre-styled FLabel component with the specified title. */ FLabel newLabel(final String title) { return new FLabel.Builder().text(title).fontSize(14).fontStyle(Font.ITALIC).build(); @@ -871,6 +880,14 @@ public class VLobby implements ILobbyView { return usedAvatars; } + List getUsedSleeves() { + final List usedSleeves = Lists.newArrayListWithCapacity(MAX_PLAYERS); + for (final PlayerPanel pp : playerPanels) { + usedSleeves.add(pp.getSleeveIndex()); + } + return usedSleeves; + } + private static final ImmutableList genderOptions = ImmutableList.of("Male", "Female", "Any"), typeOptions = ImmutableList.of("Fantasy", "Generic", "Any"); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/SleeveSelector.java b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/SleeveSelector.java new file mode 100644 index 00000000000..91fb09361ee --- /dev/null +++ b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/SleeveSelector.java @@ -0,0 +1,71 @@ +package forge.screens.home.sanctioned; + +import forge.gui.WrapLayout; +import forge.toolbox.FLabel; +import forge.toolbox.FScrollPane; +import forge.toolbox.FSkin; +import forge.view.FDialog; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("serial") +public class SleeveSelector extends FDialog { + private final List selectables = new ArrayList<>(); + private final Map sleeveMap = FSkin.getSleeves(); + + public SleeveSelector(final String playerName, final int currentIndex, final Collection usedIndices) { + this.setTitle("Select Sleeve for " + playerName); + + final JPanel pnlSleevePics = new JPanel(new WrapLayout()); + + pnlSleevePics.setOpaque(false); + pnlSleevePics.setOpaque(false); + + final FLabel initialSelection = makeSleeveLabel(sleeveMap.get(currentIndex), currentIndex, currentIndex); + pnlSleevePics.add(initialSelection); + for (final Integer i : sleeveMap.keySet()) { + if (currentIndex != i) { + pnlSleevePics.add(makeSleeveLabel(sleeveMap.get(i), i, currentIndex)); + } + } + + final int width = this.getOwner().getWidth() * 3 / 4; + final int height = this.getOwner().getHeight() * 3 / 4; + this.setPreferredSize(new Dimension(width, height)); + this.setSize(width, height); + + final FScrollPane scroller = new FScrollPane(pnlSleevePics, false); + scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + this.add(scroller, "w 100%-24px!, pushy, growy, gap 12px 0 0 0"); + this.setDefaultFocus(initialSelection); + } + + private FLabel makeSleeveLabel(final FSkin.SkinImage img0, final int index0, final int oldIndex) { + final FLabel lbl = new FLabel.Builder().icon(img0).iconScaleFactor(0.95).iconAlignX(SwingConstants.CENTER) + .iconInBackground(true).hoverable(true).selectable(true).selected(oldIndex == index0) + .unhoveredAlpha(oldIndex == index0 ? 0.9f : 0.7f).build(); + + final Dimension size = new Dimension(60, 80); + lbl.setPreferredSize(size); + lbl.setMaximumSize(size); + lbl.setMinimumSize(size); + lbl.setName("SleeveLabel" + index0); + + if (oldIndex == index0) { + lbl.setBorder(new FSkin.LineSkinBorder(FSkin.getColor(FSkin.Colors.CLR_BORDERS).alphaColor(255), 3)); + } + + selectables.add(lbl); + + return lbl; + } + + public List getSelectables() { + return this.selectables; + } +} diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java b/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java index f7e658da7ae..b0ecc7338b4 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java @@ -859,6 +859,7 @@ public class FSkin { } private static Map avatars; + private static Map sleeves; private static Map fixedFonts = new HashMap<>(); public static Font getFixedFont() { @@ -1039,7 +1040,7 @@ public class FSkin { private static String preferredDir; private static String preferredName; private static BufferedImage bimDefaultSprite, bimFavIcon, bimPreferredSprite, bimFoils, bimQuestDraftDeck, - bimOldFoils, bimDefaultAvatars, bimPreferredAvatars, bimTrophies, bimAbilities, bimManaIcons; + bimOldFoils, bimDefaultAvatars, bimPreferredAvatars, bimTrophies, bimAbilities, bimManaIcons, bimDefaultSleeve, bimDefaultSleeve2; private static int x0, y0, w0, h0, newW, newH, preferredW, preferredH; private static int[] tempCoords; private static int defaultFontSize = 12; @@ -1173,6 +1174,8 @@ public class FSkin { final File f9 = new File(defaultDir + ForgeConstants.SPRITE_FAVICONS_FILE); final File f10 = new File(defaultDir + ForgeConstants.SPRITE_ABILITY_FILE); final File f11 = new File(defaultDir + ForgeConstants.SPRITE_MANAICONS_FILE); + final File f12 = new File(defaultDir + ForgeConstants.SPRITE_SLEEVES_FILE); + final File f13 = new File(defaultDir + ForgeConstants.SPRITE_SLEEVES2_FILE); try { int p = 0; @@ -1190,6 +1193,10 @@ public class FSkin { FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); bimDefaultAvatars = ImageIO.read(f4); FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); + bimDefaultSleeve = ImageIO.read(f12); + FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); + bimDefaultSleeve2 = ImageIO.read(f13); + FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); bimTrophies = ImageIO.read(f7); FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); bimQuestDraftDeck = ImageIO.read(f8); @@ -1255,6 +1262,8 @@ public class FSkin { // Assemble avatar images assembleAvatars(); + // Sleeves + assembleSleeves(); // Images loaded; can start UI init. FView.SINGLETON_INSTANCE.setSplashProgessBarMessage("Creating display components."); @@ -1266,6 +1275,8 @@ public class FSkin { bimOldFoils.flush(); bimPreferredSprite.flush(); bimDefaultAvatars.flush(); + bimDefaultSleeve.flush(); + bimDefaultSleeve2.flush(); bimQuestDraftDeck.flush(); bimTrophies.flush(); bimAbilities.flush(); @@ -1278,6 +1289,8 @@ public class FSkin { bimOldFoils = null; bimPreferredSprite = null; bimDefaultAvatars = null; + bimDefaultSleeve = null; + bimDefaultSleeve2 = null; bimPreferredAvatars = null; bimQuestDraftDeck = null; bimTrophies = null; @@ -1379,6 +1392,10 @@ public class FSkin { return avatars; } + public static Map getSleeves() { + return sleeves; + } + public static boolean isLoaded() { return loaded; } /** @@ -1482,6 +1499,34 @@ public class FSkin { } } + private static void assembleSleeves() { + sleeves = new HashMap<>(); + int counter = 0; + Color pxTest; + + final int pw = bimDefaultSleeve.getWidth(); + final int ph = bimDefaultSleeve.getHeight(); + + for (int j = 0; j < ph; j += 500) { + for (int i = 0; i < pw; i += 360) { + pxTest = getColorFromPixel(bimDefaultSleeve.getRGB(i + 180, j + 250)); + if (pxTest.getAlpha() == 0) { continue; } + sleeves.put(counter++, new SkinImage(bimDefaultSleeve.getSubimage(i, j, 360, 500))); + } + } + //2nd set + final int aw = bimDefaultSleeve2.getWidth(); + final int ah = bimDefaultSleeve2.getHeight(); + + for (int j = 0; j < ah; j += 500) { + for (int i = 0; i < aw; i += 360) { + pxTest = getColorFromPixel(bimDefaultSleeve2.getRGB(i + 180, j + 250)); + if (pxTest.getAlpha() == 0) { continue; } + sleeves.put(counter++, new SkinImage(bimDefaultSleeve2.getSubimage(i, j, 360, 500))); + } + } + } + private static void setImage(final FSkinProp s0, final BufferedImage bim) { tempCoords = s0.getCoords(); x0 = tempCoords[0];