From 66d2701aa060bda1b96d43cecf0ca14818d4ff93 Mon Sep 17 00:00:00 2001 From: alyssa Date: Sat, 23 Aug 2025 22:09:28 +0100 Subject: [PATCH 01/13] refactor rewards to use settings abstraction --- client/src/main/java/object/RewardStar.java | 16 +- .../src/main/java/online/screen/GameRoom.java | 5 +- .../main/java/screen/AbstractAboutDialog.java | 10 +- .../java/screen/AbstractPreferencesPanel.java | 16 +- .../src/main/java/screen/ClearDataDialog.java | 11 +- .../src/main/java/screen/EntropyBidPanel.java | 3 +- client/src/main/java/screen/MainScreen.java | 14 +- .../main/java/screen/PreferencesDialog.java | 143 ------------------ .../screen/PreferencesPanelAppearance.java | 34 ++--- .../java/screen/PreferencesPanelGameplay.java | 13 +- .../main/java/screen/ReplayFilterPanel.java | 3 +- client/src/main/java/screen/RewardDialog.java | 47 +++--- client/src/main/java/screen/SimpleDialog.java | 67 -------- .../main/java/screen/StatisticsDialog.java | 3 +- .../main/java/screen/VectropyBidPanel.java | 3 +- .../src/main/java/util/AchievementsUtil.java | 28 ---- .../kotlin/achievement/AchievementUtil.kt | 19 ++- client/src/main/kotlin/achievement/Reward.kt | 21 +++ .../main/kotlin/help/FundamentalsGlossary.kt | 8 +- .../main/kotlin/help/FundamentalsTheDeck.kt | 15 +- .../main/kotlin/help/RulesVectropyBidding.kt | 8 +- .../main/kotlin/help/ToolsGameplaySettings.kt | 6 +- .../kotlin/preference/PreferenceSetting.kt | 3 + .../main/kotlin/screen/AchievementsDialog.kt | 32 ++-- client/src/main/kotlin/screen/HelpDialog.kt | 7 +- .../screen/preference/PreferencesDialog.kt | 81 ++++++++++ client/src/main/kotlin/util/ClientGlobals.kt | 2 + .../rewards/{rewardBlind.png => blind.png} | Bin .../{rewardCardReveal.png => cardReveal.png} | Bin .../rewards/{rewardCheats.png => cheats.png} | Bin ...{rewardDevelopers.png => developerSet.png} | Bin .../{rewardExtraSuits.png => extraSuits.png} | Bin .../{rewardFourColour.png => fourColours.png} | Bin .../{rewardIllegal.png => illegal.png} | Bin .../{rewardMinimalist.png => minimalist.png} | Bin ...ardNegativeJacks.png => negativeJacks.png} | Bin .../{rewardVectropy.png => vectropy.png} | Bin client/src/main/resources/update/update.bat | 10 +- core/src/main/java/util/Registry.java | 15 -- 39 files changed, 247 insertions(+), 396 deletions(-) delete mode 100644 client/src/main/java/screen/PreferencesDialog.java delete mode 100644 client/src/main/java/screen/SimpleDialog.java create mode 100644 client/src/main/kotlin/achievement/Reward.kt create mode 100644 client/src/main/kotlin/preference/PreferenceSetting.kt create mode 100644 client/src/main/kotlin/screen/preference/PreferencesDialog.kt rename client/src/main/resources/rewards/{rewardBlind.png => blind.png} (100%) rename client/src/main/resources/rewards/{rewardCardReveal.png => cardReveal.png} (100%) rename client/src/main/resources/rewards/{rewardCheats.png => cheats.png} (100%) rename client/src/main/resources/rewards/{rewardDevelopers.png => developerSet.png} (100%) rename client/src/main/resources/rewards/{rewardExtraSuits.png => extraSuits.png} (100%) rename client/src/main/resources/rewards/{rewardFourColour.png => fourColours.png} (100%) rename client/src/main/resources/rewards/{rewardIllegal.png => illegal.png} (100%) rename client/src/main/resources/rewards/{rewardMinimalist.png => minimalist.png} (100%) rename client/src/main/resources/rewards/{rewardNegativeJacks.png => negativeJacks.png} (100%) rename client/src/main/resources/rewards/{rewardVectropy.png => vectropy.png} (100%) diff --git a/client/src/main/java/object/RewardStar.java b/client/src/main/java/object/RewardStar.java index 272d9b83..cfacad16 100644 --- a/client/src/main/java/object/RewardStar.java +++ b/client/src/main/java/object/RewardStar.java @@ -1,26 +1,26 @@ package object; +import achievement.Reward; + import javax.swing.Icon; import javax.swing.JLabel; @SuppressWarnings("serial") public class RewardStar extends JLabel { - private int threshold; private String hoverDesc; - private String imageName; + private Reward reward; - public RewardStar(int threshold, String hoverDesc, String imageName) + public RewardStar(String hoverDesc, Reward reward) { super(); - this.threshold = threshold; this.hoverDesc = hoverDesc; - this.imageName = imageName; + this.reward = reward; } public boolean isUnlocked(int achievementsEarned) { - return achievementsEarned >= threshold; + return achievementsEarned >= reward.getThreshold(); } public String getHoverDesc() @@ -28,9 +28,9 @@ public String getHoverDesc() return hoverDesc; } - public String getImageName() + public Reward getReward() { - return imageName; + return reward; } @Override diff --git a/client/src/main/java/online/screen/GameRoom.java b/client/src/main/java/online/screen/GameRoom.java index dc8455ea..c287a59a 100644 --- a/client/src/main/java/online/screen/GameRoom.java +++ b/client/src/main/java/online/screen/GameRoom.java @@ -1,5 +1,6 @@ package online.screen; +import achievement.Reward; import game.*; import http.dto.RoomSummary; import object.*; @@ -212,15 +213,13 @@ else if (mode == GameMode.Vectropy) private void setIcon() { - boolean unlockedExtraSuits = rewards.getBoolean(REWARDS_BOOLEAN_EXTRA_SUITS, false); - ArrayList suits = new ArrayList<>(); suits.add("club"); suits.add("diamond"); suits.add("heart"); suits.add("spade"); - if (unlockedExtraSuits) + if (Reward.ExtraSuits.isUnlocked()) { suits.add("moon"); suits.add("star"); diff --git a/client/src/main/java/screen/AbstractAboutDialog.java b/client/src/main/java/screen/AbstractAboutDialog.java index f33094a7..0abe6aff 100644 --- a/client/src/main/java/screen/AbstractAboutDialog.java +++ b/client/src/main/java/screen/AbstractAboutDialog.java @@ -30,11 +30,11 @@ public AbstractAboutDialog() lblProductDesc.setBounds(15, 8, 184, 25); lblProductDesc.setHorizontalAlignment(SwingConstants.CENTER); getContentPane().add(lblProductDesc); - JLabel lblCreatedByAlex = new JLabel("Created by Alex Burlton"); - lblCreatedByAlex.setFont(new Font("Tahoma", Font.PLAIN, 12)); - lblCreatedByAlex.setBounds(0, 29, 214, 25); - lblCreatedByAlex.setHorizontalAlignment(SwingConstants.CENTER); - getContentPane().add(lblCreatedByAlex); + JLabel lblCreatedBy = new JLabel("Created by Alyssa Burling"); + lblCreatedBy.setFont(new Font("Tahoma", Font.PLAIN, 12)); + lblCreatedBy.setBounds(0, 29, 214, 25); + lblCreatedBy.setHorizontalAlignment(SwingConstants.CENTER); + getContentPane().add(lblCreatedBy); lblViewChangelog.setBounds(65, 65, 84, 25); lblViewChangelog.setForeground(Color.BLUE); lblViewChangelog.setFont(new Font("Tahoma", Font.BOLD, 12)); diff --git a/client/src/main/java/screen/AbstractPreferencesPanel.java b/client/src/main/java/screen/AbstractPreferencesPanel.java index ba069429..4b3dd0a0 100644 --- a/client/src/main/java/screen/AbstractPreferencesPanel.java +++ b/client/src/main/java/screen/AbstractPreferencesPanel.java @@ -1,12 +1,12 @@ package screen; -import java.awt.event.ActionListener; - -import javax.swing.AbstractButton; -import javax.swing.JPanel; - +import achievement.Reward; +import screen.preference.PreferencesDialog; import util.Registry; +import javax.swing.*; +import java.awt.event.ActionListener; + public abstract class AbstractPreferencesPanel extends JPanel implements Registry, ActionListener @@ -17,11 +17,11 @@ public abstract class AbstractPreferencesPanel extends JPanel public abstract boolean valid(); public abstract void savePreferences(); - protected void toggleLockedComponent(AbstractButton c, String rewardsStr) + protected void toggleLockedComponent(AbstractButton c, Reward requiredReward) { - boolean unlocked = rewards.getBoolean(rewardsStr, false); + boolean unlocked = requiredReward.isUnlocked(); String text = unlocked? c.getText() : "Locked"; - String toolTipText = unlocked? c.getToolTipText() : ""; + String toolTipText = unlocked? c.getToolTipText() : "Unlock at " + requiredReward.getThreshold() + " achievements"; c.setText(text); c.setToolTipText(toolTipText); diff --git a/client/src/main/java/screen/ClearDataDialog.java b/client/src/main/java/screen/ClearDataDialog.java index 039a4abc..a7f354da 100644 --- a/client/src/main/java/screen/ClearDataDialog.java +++ b/client/src/main/java/screen/ClearDataDialog.java @@ -10,6 +10,7 @@ import java.awt.event.WindowEvent; import static util.ClientGlobals.achievementStore; +import static util.ClientGlobals.rewardStore; public class ClearDataDialog extends JDialog implements ActionListener, @@ -109,7 +110,7 @@ private void clearData() } achievementStore.clear(); - RegistryUtil.clearNode(rewards); + rewardStore.clear(); RegistryUtil.clearNode(savedGame); resetPreferences(); DialogUtilNew.showInfo("Achievements and statistics were reset successfully."); @@ -168,13 +169,7 @@ else if (!result.isEmpty()) private void removeStatisticsVariablesFromNode() { ScreenCache.get(MainScreen.class).resetStartTime(); - achievementStore.delete(AchievementSetting.TimePlayed); - achievementStore.delete(AchievementSetting.BestStreak); - achievementStore.delete(AchievementSetting.CurrentStreak); - achievementStore.delete(AchievementSetting.EntropyGamesPlayed); - achievementStore.delete(AchievementSetting.VectropyGamesPlayed); - achievementStore.delete(AchievementSetting.EntropyGamesWon); - achievementStore.delete(AchievementSetting.VectropyGamesWon); + achievementStore.clear(); } private void resetPreferences() diff --git a/client/src/main/java/screen/EntropyBidPanel.java b/client/src/main/java/screen/EntropyBidPanel.java index fb637ef5..64640cb9 100644 --- a/client/src/main/java/screen/EntropyBidPanel.java +++ b/client/src/main/java/screen/EntropyBidPanel.java @@ -24,6 +24,7 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import achievement.Reward; import game.EntropyBidAction; import game.Suit; import util.Debug; @@ -189,7 +190,7 @@ private void setIllegalButtonState() { if (!online) { - illegalAllowed |= rewards.getBoolean(REWARDS_BOOLEAN_ILLEGAL, false); + illegalAllowed |= Reward.Illegal.isUnlocked(); } btnIllegal.setVisible(illegalAllowed); diff --git a/client/src/main/java/screen/MainScreen.java b/client/src/main/java/screen/MainScreen.java index fb98d6cb..c4ae8f86 100644 --- a/client/src/main/java/screen/MainScreen.java +++ b/client/src/main/java/screen/MainScreen.java @@ -2,6 +2,7 @@ import achievement.AchievementSetting; import achievement.AchievementUtilKt; +import achievement.Reward; import bean.AbstractDevScreen; import game.GameMode; import game.PlayerAction; @@ -11,6 +12,7 @@ import online.screen.TestHarness; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import screen.preference.PreferencesDialog; import settings.Setting; import settings.SettingChangeListener; import util.*; @@ -30,6 +32,7 @@ import java.util.prefs.Preferences; import static achievement.AchievementUtilKt.getAchievementsEarned; +import static achievement.AchievementUtilKt.unlockRewards; import static screen.ScreenCacheKt.IN_GAME_REPLAY; import static screen.online.PlayOnlineDialogKt.showPlayOnlineDialog; import static util.ClientGlobals.achievementStore; @@ -648,7 +651,7 @@ private void selectGameScreen(GameMode gameMode) public boolean commandsEnabled() { return ClientUtil.devMode - || rewards.getBoolean(Registry.REWARDS_BOOLEAN_CHEATS, false); + || Reward.Cheats.isUnlocked(); } @Override @@ -688,6 +691,11 @@ else if (command.equals("bluescreenofdeath")) { AchievementsUtil.unlockBlueScreenOfDeath(); } + else if (command.startsWith("unlock ")) + { + var threshold = command.replace("unlock ", ""); + unlockRewards(Integer.parseInt(threshold)); + } else { textToShow = gamePanel.processCommand(command); @@ -720,7 +728,7 @@ else if (command.startsWith("unlock ")) { int spaceIndex = command.indexOf(' '); int achievements = Integer.parseInt(command.substring(spaceIndex+1)); - AchievementsUtil.unlockRewards(achievements); + unlockRewards(achievements); } else if (command.equals("stacks")) { @@ -751,7 +759,7 @@ public void onStart() setViewLogsVisibility(); restartTimers(); - AchievementsUtil.unlockRewards(getAchievementsEarned()); + unlockRewards(getAchievementsEarned()); } private void cleanUpReplayNodes() diff --git a/client/src/main/java/screen/PreferencesDialog.java b/client/src/main/java/screen/PreferencesDialog.java deleted file mode 100644 index 24aeced5..00000000 --- a/client/src/main/java/screen/PreferencesDialog.java +++ /dev/null @@ -1,143 +0,0 @@ -package screen; - -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.ArrayList; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTabbedPane; -import javax.swing.SwingConstants; - -import game.GameMode; -import util.ApiUtil; -import util.Debug; -import util.Registry; - -/** - * Created by Alex Burlton (08/10/13) - */ -public class PreferencesDialog extends JDialog - implements Registry, - ActionListener -{ - public PreferencesDialog() - { - try - { - getContentPane().setLayout(new BorderLayout(0, 0)); - tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); - getContentPane().add(tabbedPane); - appearanceScrollPane.getVerticalScrollBar().setUnitIncrement(16); - tabbedPane.addTab("Gameplay", null, gameplayPanel, null); - tabbedPane.addTab("Players", null, playersPanel, null); - appearanceScrollPane.setViewportView(appearancePanel); - tabbedPane.addTab("Appearance", null, appearanceScrollPane, null); - tabbedPane.addTab("Miscellaneous", null, miscPanel, null); - getContentPane().add(okCancelPanel, BorderLayout.SOUTH); - okCancelPanel.setBorder(BorderFactory.createEmptyBorder(10, 150, 10, 150)); - okCancelPanel.setLayout(new BorderLayout(0, 0)); - okCancelPanel.add(btnOk, BorderLayout.WEST); - okCancelPanel.add(btnCancel, BorderLayout.EAST); - - btnOk.addActionListener(this); - btnCancel.addActionListener(this); - - initVariables(); - } - catch (Throwable t) - { - Debug.stackTrace(t); - } - } - - private final JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP); - private final PreferencesPanelGameplay gameplayPanel = new PreferencesPanelGameplay(); - private final JScrollPane appearanceScrollPane = new JScrollPane(); - private final PreferencesPanelAppearance appearancePanel = new PreferencesPanelAppearance(); - private final PreferencesPanelPlayers playersPanel = new PreferencesPanelPlayers(); - private final PreferencesPanelMisc miscPanel = new PreferencesPanelMisc(); - private final JPanel okCancelPanel = new JPanel(); - private final JButton btnOk = new JButton("Ok"); - private final JButton btnCancel = new JButton("Cancel"); - - public void initVariables() - { - ArrayList childPanels = getChildPanels(); - for (int i=0; i childPanels = getChildPanels(); - for (int i=0; i getChildPanels() - { - ArrayList ret = new ArrayList<>(); - - ret.add(gameplayPanel); - ret.add(appearancePanel); - ret.add(playersPanel); - ret.add(miscPanel); - - return ret; - } - - @Override - public void actionPerformed(ActionEvent arg0) - { - Object source = arg0.getSource(); - - if (source == btnOk) - { - if (valid()) - { - gameplayPanel.savePreferences(); - appearancePanel.savePreferences(); - playersPanel.savePreferences(); - miscPanel.savePreferences(); - closeDialog(); - } - } - else if (source == btnCancel) - { - closeDialog(); - } - else - { - Debug.stackTrace("Unexpected actionPerformed: " + source); - } - } - - private void closeDialog() - { - ApiUtil.clearCache(); - dispose(); - } -} \ No newline at end of file diff --git a/client/src/main/java/screen/PreferencesPanelAppearance.java b/client/src/main/java/screen/PreferencesPanelAppearance.java index 94946223..f3e1aed0 100644 --- a/client/src/main/java/screen/PreferencesPanelAppearance.java +++ b/client/src/main/java/screen/PreferencesPanelAppearance.java @@ -26,6 +26,7 @@ import javax.swing.border.LineBorder; import javax.swing.text.DefaultCaret; +import achievement.Reward; import bean.ComboBoxItem; import object.DisabledComboBoxModel; import util.GameUtil; @@ -225,9 +226,9 @@ private void getVariablesFromPrefs() private void hideLockedFields() { - toggleLockedComponent(cbFourColour, REWARDS_BOOLEAN_FOUR_COLOURS); - toggleLockedComponent(rdbtnMinimalistDesign, REWARDS_BOOLEAN_MINIMALIST_DECK); - toggleLockedComponent(rdbtnDeveloperJokers, REWARDS_BOOLEAN_DEVELOPER_JOKERS); + toggleLockedComponent(cbFourColour, Reward.FourColours); + toggleLockedComponent(rdbtnMinimalistDesign, Reward.MinimalistDeck); + toggleLockedComponent(rdbtnDeveloperJokers, Reward.DeveloperSet); } private void refreshDeckPreview() @@ -277,30 +278,29 @@ private Vector> initialiseBacksVector() backs.addElement(new ComboBoxItem<>(BACK_CODE_CLASSIC_BLUE, "Blue")); backs.addElement(new ComboBoxItem<>("backRed", "Red")); - addIfUnlocked(backs, new ComboBoxItem<>("backGreen", "Green"), 5, REWARDS_BOOLEAN_FOUR_COLOURS); - addIfUnlocked(backs, new ComboBoxItem<>("backPurple", "Purple"), 10, REWARDS_BOOLEAN_NEGATIVE_JACKS); - addIfUnlocked(backs, new ComboBoxItem<>("backOrange", "Orange"), 15, REWARDS_BOOLEAN_BLIND); - addIfUnlocked(backs, new ComboBoxItem<>("backLightBlue", "Light Blue"), 20, REWARDS_BOOLEAN_MINIMALIST_DECK); - addIfUnlocked(backs, new ComboBoxItem<>("backPink", "Pink"), 25, REWARDS_BOOLEAN_VECTROPY); - addIfUnlocked(backs, new ComboBoxItem<>("backSilver", "Silver"), 30, REWARDS_BOOLEAN_CARD_REVEAL); - addIfUnlocked(backs, new ComboBoxItem<>("backGold", "Gold"), 35, REWARDS_BOOLEAN_EXTRA_SUITS); - addIfUnlocked(backs, new ComboBoxItem<>("backMatrix", "Matrix"), 40, REWARDS_BOOLEAN_ILLEGAL); - addIfUnlocked(backs, new ComboBoxItem<>("backCosmic", "Cosmic"), 45, REWARDS_BOOLEAN_DEVELOPER_JOKERS); - addIfUnlocked(backs, new ComboBoxItem<>("backRainbow", "Rainbow"), 50, REWARDS_BOOLEAN_CHEATS); + addIfUnlocked(backs, new ComboBoxItem<>("backGreen", "Green"), Reward.FourColours); + addIfUnlocked(backs, new ComboBoxItem<>("backPurple", "Purple"), Reward.NegativeJacks); + addIfUnlocked(backs, new ComboBoxItem<>("backOrange", "Orange"), Reward.Blind); + addIfUnlocked(backs, new ComboBoxItem<>("backLightBlue", "Light Blue"), Reward.MinimalistDeck); + addIfUnlocked(backs, new ComboBoxItem<>("backPink", "Pink"), Reward.Vectropy); + addIfUnlocked(backs, new ComboBoxItem<>("backSilver", "Silver"), Reward.CardReveal); + addIfUnlocked(backs, new ComboBoxItem<>("backGold", "Gold"), Reward.ExtraSuits); + addIfUnlocked(backs, new ComboBoxItem<>("backMatrix", "Matrix"), Reward.Illegal); + addIfUnlocked(backs, new ComboBoxItem<>("backCosmic", "Cosmic"), Reward.DeveloperSet); + addIfUnlocked(backs, new ComboBoxItem<>("backRainbow", "Rainbow"), Reward.Cheats); return backs; } private void addIfUnlocked(Vector> backs, ComboBoxItem item, - int achievementsRequired, String rewardStr) + Reward reward) { - boolean unlocked = rewards.getBoolean(rewardStr, false); - if (unlocked) + if (reward.isUnlocked()) { backs.addElement(item); } else { - ComboBoxItem disabledItem = new ComboBoxItem<>("", achievementsRequired + " achievements to unlock"); + ComboBoxItem disabledItem = new ComboBoxItem<>("", reward.getThreshold() + " achievements to unlock"); disabledItem.setEnabled(false); backs.addElement(disabledItem); } diff --git a/client/src/main/java/screen/PreferencesPanelGameplay.java b/client/src/main/java/screen/PreferencesPanelGameplay.java index b158e5db..cc4c474b 100644 --- a/client/src/main/java/screen/PreferencesPanelGameplay.java +++ b/client/src/main/java/screen/PreferencesPanelGameplay.java @@ -21,6 +21,7 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import achievement.Reward; import game.GameMode; import util.Debug; @@ -254,12 +255,12 @@ private void adjustHandicapSpinner() private void hideLockedFields() { - toggleLockedComponent(cbNegativeJacks, REWARDS_BOOLEAN_NEGATIVE_JACKS); - toggleLockedComponent(cbPlayBlind, REWARDS_BOOLEAN_BLIND); - toggleLockedComponent(rdbtnVectropy, REWARDS_BOOLEAN_VECTROPY); - toggleLockedComponent(cbPlayersRevealCards, REWARDS_BOOLEAN_CARD_REVEAL); - toggleLockedComponent(cbIncludeMoons, REWARDS_BOOLEAN_EXTRA_SUITS); - toggleLockedComponent(cbIncludeStars, REWARDS_BOOLEAN_EXTRA_SUITS); + toggleLockedComponent(cbNegativeJacks, Reward.NegativeJacks); + toggleLockedComponent(cbPlayBlind, Reward.Blind); + toggleLockedComponent(rdbtnVectropy, Reward.Vectropy); + toggleLockedComponent(cbPlayersRevealCards, Reward.CardReveal); + toggleLockedComponent(cbIncludeMoons, Reward.ExtraSuits); + toggleLockedComponent(cbIncludeStars, Reward.ExtraSuits); } @Override diff --git a/client/src/main/java/screen/ReplayFilterPanel.java b/client/src/main/java/screen/ReplayFilterPanel.java index 5e470b22..62e2570c 100644 --- a/client/src/main/java/screen/ReplayFilterPanel.java +++ b/client/src/main/java/screen/ReplayFilterPanel.java @@ -19,6 +19,7 @@ import javax.swing.SwingConstants; import javax.swing.border.EtchedBorder; +import achievement.Reward; import object.FlagImage; import util.Debug; import util.DialogUtil; @@ -225,7 +226,7 @@ public ReplayFilterPanel() public void setMoonAndStarVisibility() { - boolean unlockedExtraSuits = rewards.getBoolean(REWARDS_BOOLEAN_EXTRA_SUITS, false); + boolean unlockedExtraSuits = Reward.ExtraSuits.isUnlocked(); GridLayout layout = (GridLayout)flagPanel.getLayout(); flagPanel.remove(moonPanel); flagPanel.remove(starPanel); diff --git a/client/src/main/java/screen/RewardDialog.java b/client/src/main/java/screen/RewardDialog.java index 36af367d..7598310b 100644 --- a/client/src/main/java/screen/RewardDialog.java +++ b/client/src/main/java/screen/RewardDialog.java @@ -1,5 +1,7 @@ package screen; +import achievement.Reward; + import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; @@ -20,33 +22,20 @@ public class RewardDialog extends JDialog implements ActionListener { - public static final String REWARD_BANNER_FOUR_COLOUR = "rewardFourColour.png"; - //public static final String REWARD_BANNER_JOKERS = "rewardJokers.png"; - public static final String REWARD_BANNER_NEGATIVE_JACKS = "rewardNegativeJacks.png"; - public static final String REWARD_BANNER_BLIND = "rewardBlind.png"; - public static final String REWARD_BANNER_MINIMALIST = "rewardMinimalist.png"; - public static final String REWARD_BANNER_VECTROPY = "rewardVectropy.png"; - //public static final String REWARD_BANNER_HANDICAP = "rewardHandicap.png"; - public static final String REWARD_BANNER_CARD_REVEAL = "rewardCardReveal.png"; - public static final String REWARD_BANNER_DEVELOPERS = "rewardDevelopers.png"; - public static final String REWARD_BANNER_ILLEGAL = "rewardIllegal.png"; - public static final String REWARD_BANNER_EXTRA_SUITS = "rewardExtraSuits.png"; - public static final String REWARD_BANNER_CHEATS = "rewardCheats.png"; - - public RewardDialog(String imageName) + public RewardDialog(Reward reward) { topPanel.setLayout(new BorderLayout(0, 0)); rewardTitle.setFont(new Font("Tahoma", Font.BOLD, 16)); rewardTitle.setHorizontalAlignment(SwingConstants.CENTER); rewardTitle.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); topPanel.add(rewardTitle, BorderLayout.NORTH); - ImageIcon banner = new ImageIcon(getClass().getResource("/rewards/" + imageName)); + ImageIcon banner = new ImageIcon(getClass().getResource("/rewards/" + reward.getSettingName() + ".png")); imageBanner.setHorizontalAlignment(SwingConstants.CENTER); imageBanner.setIcon(banner); topPanel.add(imageBanner, BorderLayout.SOUTH); getContentPane().add(topPanel, BorderLayout.NORTH); - setRewardDescriptionAndDialogSize(imageName); + setRewardDescriptionAndDialogSize(reward); rewardDescription.setEditable(false); rewardDescription.setOpaque(false); rewardDescription.setBorder(BorderFactory.createEmptyBorder(15, 10, 10, 10)); @@ -67,9 +56,9 @@ public RewardDialog(String imageName) private final JButton btnOk = new JButton("Ok"); - public static void showDialog(String imageName) + public static void showDialog(Reward reward) { - RewardDialog dialog = new RewardDialog(imageName); + RewardDialog dialog = new RewardDialog(reward); dialog.setLocationRelativeTo(null); dialog.setResizable(false); @@ -84,11 +73,11 @@ public void actionPerformed(ActionEvent arg0) setVisible(false); } - private void setRewardDescriptionAndDialogSize(String imageName) + private void setRewardDescriptionAndDialogSize(Reward reward) { String rewardStr = ""; - if (imageName.equals(REWARD_BANNER_BLIND)) + if (reward == Reward.Blind) { rewardTitle.setText("Blind play unlocked!"); rewardStr = "Ramp up the challenge by making decisions without looking at your cards!" @@ -99,7 +88,7 @@ private void setRewardDescriptionAndDialogSize(String imageName) rewardDescription.setText(rewardStr); setSize(new Dimension(400, 410)); } - else if (imageName.equals(REWARD_BANNER_DEVELOPERS)) + else if (reward == Reward.DeveloperSet) { rewardTitle.setText("'Developers' joker set unlocked!"); rewardStr = "These jokers feature the faces of four people who helped to develop Entropy." @@ -108,7 +97,7 @@ else if (imageName.equals(REWARD_BANNER_DEVELOPERS)) rewardDescription.setText(rewardStr); setSize(new Dimension(400, 330)); } - else if (imageName.equals(REWARD_BANNER_FOUR_COLOUR)) + else if (reward == Reward.FourColours) { rewardTitle.setText("Four colour deck unlocked!"); rewardStr = "You can now play with a four-colour deck, where clubs are green and diamonds are blue." @@ -117,7 +106,7 @@ else if (imageName.equals(REWARD_BANNER_FOUR_COLOUR)) rewardDescription.setText(rewardStr); setSize(new Dimension(400, 330)); } - else if (imageName.equals(REWARD_BANNER_CARD_REVEAL)) + else if (reward == Reward.CardReveal) { rewardTitle.setText("Card reveal unlocked!"); rewardStr = "Add extra pressure to the game by forcing players to reveal their cards!" @@ -128,7 +117,7 @@ else if (imageName.equals(REWARD_BANNER_CARD_REVEAL)) rewardDescription.setText(rewardStr); setSize(new Dimension(400, 390)); } - else if (imageName.equals(REWARD_BANNER_NEGATIVE_JACKS)) + else if (reward == Reward.NegativeJacks) { rewardTitle.setText("Negative jacks unlocked!"); rewardStr = "Spice up the deck by makings Jacks worth -1 of their suit!" @@ -137,7 +126,7 @@ else if (imageName.equals(REWARD_BANNER_NEGATIVE_JACKS)) rewardDescription.setText(rewardStr); setSize(new Dimension(400, 310)); } - else if (imageName.equals(REWARD_BANNER_MINIMALIST)) + else if (reward == Reward.MinimalistDeck) { rewardTitle.setText("'Minimalist' deck design unlocked!"); rewardStr = "Go for a more minimalist feel with this new deck design." @@ -146,7 +135,7 @@ else if (imageName.equals(REWARD_BANNER_MINIMALIST)) rewardDescription.setText(rewardStr); setSize(new Dimension(400, 310)); } - else if (imageName.equals(REWARD_BANNER_VECTROPY)) + else if (reward == Reward.Vectropy) { rewardTitle.setText("Vectropy unlocked!"); rewardStr = "Vectropy is a variant where you have to bid in all four suits at once. " @@ -156,7 +145,7 @@ else if (imageName.equals(REWARD_BANNER_VECTROPY)) rewardDescription.setText(rewardStr); setSize(new Dimension(400, 350)); } - else if (imageName.equals(REWARD_BANNER_ILLEGAL)) + else if (reward == Reward.Illegal) { rewardTitle.setText("'Illegal' option unlocked!"); rewardStr = "You can now shout 'Illegal!' in response to a bid that you think is perfect! " @@ -166,7 +155,7 @@ else if (imageName.equals(REWARD_BANNER_ILLEGAL)) rewardDescription.setText(rewardStr); setSize(new Dimension(400, 370)); } - else if (imageName.equals(REWARD_BANNER_EXTRA_SUITS)) + else if (reward == Reward.ExtraSuits) { rewardTitle.setText("Extra suits unlocked!"); rewardStr = "You can now play with Stars and Moons, making for up to 6 suits in total! " @@ -176,7 +165,7 @@ else if (imageName.equals(REWARD_BANNER_EXTRA_SUITS)) rewardDescription.setText(rewardStr); setSize(new Dimension(400, 370)); } - else if (imageName.equals(REWARD_BANNER_CHEATS)) + else if (reward == Reward.Cheats) { rewardTitle.setText("Cheats unlocked!"); rewardStr = "Now you can use certain codes to cheat on your opponents, and even access hidden screens!" diff --git a/client/src/main/java/screen/SimpleDialog.java b/client/src/main/java/screen/SimpleDialog.java deleted file mode 100644 index 451bbff0..00000000 --- a/client/src/main/java/screen/SimpleDialog.java +++ /dev/null @@ -1,67 +0,0 @@ -package screen; - -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JPanel; - -import util.Debug; - -public abstract class SimpleDialog extends JDialog - implements ActionListener -{ - public SimpleDialog() - { - getContentPane().add(panelOkCancel, BorderLayout.SOUTH); - - panelOkCancel.add(btnOk); - panelOkCancel.add(btnCancel); - - btnCancel.setVisible(allowCancel()); - - btnOk.addActionListener(this); - btnCancel.addActionListener(this); - } - - protected final JPanel panelOkCancel = new JPanel(); - private final JButton btnOk = new JButton("Ok"); - private final JButton btnCancel = new JButton("Cancel"); - - /** - * Abstract methods - */ - public abstract void okPressed(); - - /** - * Default methods - */ - public boolean allowCancel() - { - return true; - } - public void cancelPressed() - { - dispose(); - } - - @Override - public void actionPerformed(ActionEvent arg0) - { - JButton src = (JButton)arg0.getSource(); - if (src == btnOk) - { - okPressed(); - } - else if (src == btnCancel) - { - cancelPressed(); - } - else - { - Debug.stackTrace("Unexpected button pressed: " + src.getText()); - } - } -} diff --git a/client/src/main/java/screen/StatisticsDialog.java b/client/src/main/java/screen/StatisticsDialog.java index 15ab3be0..7fb579ae 100644 --- a/client/src/main/java/screen/StatisticsDialog.java +++ b/client/src/main/java/screen/StatisticsDialog.java @@ -24,6 +24,7 @@ import javax.swing.SwingConstants; import achievement.AchievementSetting; +import achievement.Reward; import util.DateUtil; import util.Debug; import util.Registry; @@ -42,7 +43,7 @@ public StatisticsDialog() { try { - vectropyUnlocked = rewards.getBoolean(REWARDS_BOOLEAN_VECTROPY, false); + vectropyUnlocked = Reward.Vectropy.isUnlocked(); getContentPane().setLayout(new BorderLayout(0, 0)); panel_1 = new Panel(); diff --git a/client/src/main/java/screen/VectropyBidPanel.java b/client/src/main/java/screen/VectropyBidPanel.java index cca33d54..0ff9258d 100644 --- a/client/src/main/java/screen/VectropyBidPanel.java +++ b/client/src/main/java/screen/VectropyBidPanel.java @@ -24,6 +24,7 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import achievement.Reward; import game.Suit; import game.VectropyBidAction; import util.Debug; @@ -256,7 +257,7 @@ private void setIllegalButtonState() { if (!online) { - illegalAllowed |= rewards.getBoolean(REWARDS_BOOLEAN_ILLEGAL, false); + illegalAllowed |= Reward.Illegal.isUnlocked(); } btnIllegal.setVisible(illegalAllowed); diff --git a/client/src/main/java/util/AchievementsUtil.java b/client/src/main/java/util/AchievementsUtil.java index 90150945..e384858a 100644 --- a/client/src/main/java/util/AchievementsUtil.java +++ b/client/src/main/java/util/AchievementsUtil.java @@ -5,9 +5,7 @@ import game.PlayerAction; import object.Player; import online.screen.EntropyLobby; -import screen.HelpDialog; import screen.MainScreen; -import screen.RewardDialog; import screen.ScreenCache; import utils.Achievement; @@ -448,32 +446,6 @@ public static void unlockBlueScreenOfDeath() { unlockAchievement(Achievement.BlueScreenOfDeath); } - - public static void unlockRewards(int achievementsEarned) - { - unlockIfRequired(achievementsEarned, 5, REWARDS_BOOLEAN_FOUR_COLOURS, RewardDialog.REWARD_BANNER_FOUR_COLOUR); - unlockIfRequired(achievementsEarned, 10, REWARDS_BOOLEAN_NEGATIVE_JACKS, RewardDialog.REWARD_BANNER_NEGATIVE_JACKS); - unlockIfRequired(achievementsEarned, 15, REWARDS_BOOLEAN_BLIND, RewardDialog.REWARD_BANNER_BLIND); - unlockIfRequired(achievementsEarned, 20, REWARDS_BOOLEAN_MINIMALIST_DECK, RewardDialog.REWARD_BANNER_MINIMALIST); - unlockIfRequired(achievementsEarned, 25, REWARDS_BOOLEAN_VECTROPY, RewardDialog.REWARD_BANNER_VECTROPY); - unlockIfRequired(achievementsEarned, 30, REWARDS_BOOLEAN_CARD_REVEAL, RewardDialog.REWARD_BANNER_CARD_REVEAL); - unlockIfRequired(achievementsEarned, 35, REWARDS_BOOLEAN_EXTRA_SUITS, RewardDialog.REWARD_BANNER_EXTRA_SUITS); - unlockIfRequired(achievementsEarned, 40, REWARDS_BOOLEAN_ILLEGAL, RewardDialog.REWARD_BANNER_ILLEGAL); - unlockIfRequired(achievementsEarned, 45, REWARDS_BOOLEAN_DEVELOPER_JOKERS, RewardDialog.REWARD_BANNER_DEVELOPERS); - unlockIfRequired(achievementsEarned, 50, REWARDS_BOOLEAN_CHEATS, RewardDialog.REWARD_BANNER_CHEATS); - - //Always refresh here in case there are new pages - ScreenCache.get(HelpDialog.class).refreshNodes(""); - } - private static void unlockIfRequired(int achievementsEarned, int threshold, String registryNode, String imageName) - { - if (achievementsEarned >= threshold - && !rewards.getBoolean(registryNode, false)) - { - rewards.putBoolean(registryNode, true); - RewardDialog.showDialog(imageName); - } - } public static void updateAndUnlockSocial(ConcurrentHashMap hmPlayerByAdjustedPlayerNumber) { diff --git a/client/src/main/kotlin/achievement/AchievementUtil.kt b/client/src/main/kotlin/achievement/AchievementUtil.kt index beb30b90..c27e6e0a 100644 --- a/client/src/main/kotlin/achievement/AchievementUtil.kt +++ b/client/src/main/kotlin/achievement/AchievementUtil.kt @@ -2,10 +2,11 @@ package achievement import javax.swing.ImageIcon import screen.AchievementsDialog +import screen.HelpDialog import screen.MainScreen +import screen.RewardDialog import screen.ScreenCache import settings.Setting -import util.AchievementsUtil import util.ClientGlobals import util.ClientGlobals.achievementStore import util.ClientUtil @@ -40,7 +41,21 @@ fun unlockAchievement(achievement: Achievement) { ClientGlobals.sessionApi.updateAchievementCount(achievementsEarned) } - AchievementsUtil.unlockRewards(achievementsEarned) + unlockRewards(achievementsEarned) +} + +fun unlockRewards(achievementsEarned: Int) { + Reward.entries.forEach { reward -> + if ( + achievementsEarned >= reward.threshold && !ClientGlobals.rewardStore.get(reward.setting) + ) { + ClientGlobals.rewardStore.save(reward.setting, true) + RewardDialog.showDialog(reward) + } + } + + // Always refresh here in case there are new pages + ScreenCache.get().refreshNodes("") } fun updateAndUnlockVanity() { diff --git a/client/src/main/kotlin/achievement/Reward.kt b/client/src/main/kotlin/achievement/Reward.kt new file mode 100644 index 00000000..12604849 --- /dev/null +++ b/client/src/main/kotlin/achievement/Reward.kt @@ -0,0 +1,21 @@ +package achievement + +import settings.Setting +import util.ClientGlobals + +enum class Reward(val settingName: String, val threshold: Int) { + FourColours("fourColours", 5), + NegativeJacks("negativeJacks", 10), + Blind("blind", 15), + MinimalistDeck("minimalist", 20), + Vectropy("vectropy", 25), + CardReveal("cardReveal", 30), + ExtraSuits("extraSuits", 35), + Illegal("illegal", 40), + DeveloperSet("developerSet", 45), + Cheats("cheats", 50); + + val setting: Setting = Setting(settingName, false) + + fun isUnlocked() = ClientGlobals.rewardStore.get(setting) +} diff --git a/client/src/main/kotlin/help/FundamentalsGlossary.kt b/client/src/main/kotlin/help/FundamentalsGlossary.kt index e199d1dd..00812256 100644 --- a/client/src/main/kotlin/help/FundamentalsGlossary.kt +++ b/client/src/main/kotlin/help/FundamentalsGlossary.kt @@ -1,12 +1,12 @@ package help +import achievement.Reward import java.awt.Color import java.awt.Font import javax.swing.JTextPane import util.EntropyColour -import util.Registry -class FundamentalsGlossary : HelpPanel(), Registry { +class FundamentalsGlossary : HelpPanel() { override val nodeName = "Glossary" private val title = JTextPane() @@ -31,11 +31,9 @@ class FundamentalsGlossary : HelpPanel(), Registry { override fun searchTermsToExclude() = listOf("perfect", "challenge") override fun refresh() { - val blindUnlocked = Registry.rewards.getBoolean(Registry.REWARDS_BOOLEAN_BLIND, false) - var glossaryText = "\r\n
    \r\n" - if (blindUnlocked) { + if (Reward.Blind.isUnlocked()) { glossaryText += "
  • Blind: Playing blind means not looking at your cards.
  • \r\n" } diff --git a/client/src/main/kotlin/help/FundamentalsTheDeck.kt b/client/src/main/kotlin/help/FundamentalsTheDeck.kt index 9e95debf..91da840a 100644 --- a/client/src/main/kotlin/help/FundamentalsTheDeck.kt +++ b/client/src/main/kotlin/help/FundamentalsTheDeck.kt @@ -1,5 +1,6 @@ package help +import achievement.Reward import game.CLUBS_SYMBOL import game.DIAMONDS_SYMBOL import game.HEARTS_SYMBOL @@ -12,9 +13,8 @@ import javax.swing.JLabel import javax.swing.JTextPane import javax.swing.SwingConstants import util.EntropyColour -import util.Registry -class FundamentalsTheDeck : HelpPanel(), Registry { +class FundamentalsTheDeck : HelpPanel() { override val nodeName = "The Deck" private var clubString = "clubs (${CLUBS_SYMBOL})" @@ -102,7 +102,7 @@ class FundamentalsTheDeck : HelpPanel(), Registry { override fun searchTermsToExclude() = listOf("bidding") - private fun setPaneOneText(moonsAndStars: Boolean) { + private fun setPaneOneText() { var paneOneText = ("For the standard game, a normal deck of 52 cards is used. This deck is made up of four suits: " + clubString + @@ -111,7 +111,7 @@ class FundamentalsTheDeck : HelpPanel(), Registry { ", hearts (${HEARTS_SYMBOL}) and spades (${SPADES_SYMBOL}), " + "each of 13 cards. ") - if (moonsAndStars) { + if (Reward.ExtraSuits.isUnlocked()) { paneOneText += "Two optional suits, $moonString and stars " paneOneText += "(" + @@ -148,8 +148,7 @@ class FundamentalsTheDeck : HelpPanel(), Registry { MOONS_SYMBOL + ")" - val moonsAndStars = Registry.rewards.getBoolean(Registry.REWARDS_BOOLEAN_EXTRA_SUITS, false) - setPaneOneText(moonsAndStars) + setPaneOneText() if (fourColours) { clubLabel.foreground = Color(0, 128, 0) @@ -163,9 +162,7 @@ class FundamentalsTheDeck : HelpPanel(), Registry { } private fun refreshSuitRankingVisibility() { - val moonsAndStars = Registry.rewards.getBoolean(Registry.REWARDS_BOOLEAN_EXTRA_SUITS, false) - - if (moonsAndStars) { + if (Reward.ExtraSuits.isUnlocked()) { moonLabel.isVisible = true starLabel.isVisible = true rightmostLabel.isVisible = true diff --git a/client/src/main/kotlin/help/RulesVectropyBidding.kt b/client/src/main/kotlin/help/RulesVectropyBidding.kt index 181dca78..70e145de 100644 --- a/client/src/main/kotlin/help/RulesVectropyBidding.kt +++ b/client/src/main/kotlin/help/RulesVectropyBidding.kt @@ -1,12 +1,12 @@ package help +import achievement.Reward import java.awt.Color import java.awt.Font import javax.swing.JTextPane import util.EntropyColour -import util.Registry -class RulesVectropyBidding : HelpPanel(), Registry { +class RulesVectropyBidding : HelpPanel() { override val nodeName = "Bidding" private val title = JTextPane() @@ -58,8 +58,6 @@ class RulesVectropyBidding : HelpPanel(), Registry { } private fun setPaneOneText() { - val extraSuits = Registry.rewards.getBoolean(Registry.REWARDS_BOOLEAN_EXTRA_SUITS, false) - var text = "A round starts with the first person to play bidding. At the start of a new game, " text += @@ -74,7 +72,7 @@ class RulesVectropyBidding : HelpPanel(), Registry { "(\u2663, \u2666, " text += "\u2665, \u2660). " - if (extraSuits) { + if (Reward.ExtraSuits.isUnlocked()) { text += "This vector naturally extends if additional suits are in play. " } diff --git a/client/src/main/kotlin/help/ToolsGameplaySettings.kt b/client/src/main/kotlin/help/ToolsGameplaySettings.kt index da087b1c..8767c571 100644 --- a/client/src/main/kotlin/help/ToolsGameplaySettings.kt +++ b/client/src/main/kotlin/help/ToolsGameplaySettings.kt @@ -1,5 +1,6 @@ package help +import achievement.Reward import java.awt.Color import java.awt.Dimension import java.awt.Font @@ -8,9 +9,8 @@ import javax.swing.JLabel import javax.swing.JPanel import javax.swing.JTextPane import util.EntropyColour -import util.Registry -class ToolsGameplaySettings : HelpPanel(), Registry { +class ToolsGameplaySettings : HelpPanel() { override val nodeName = "Gameplay Settings" private val title = JTextPane() @@ -132,7 +132,7 @@ class ToolsGameplaySettings : HelpPanel(), Registry { } override fun refresh() { - val unlockedBlind = Registry.rewards.getBoolean(Registry.REWARDS_BOOLEAN_BLIND, false) + val unlockedBlind = Reward.Blind.isUnlocked() blindPanel.isVisible = unlockedBlind if (unlockedBlind) { diff --git a/client/src/main/kotlin/preference/PreferenceSetting.kt b/client/src/main/kotlin/preference/PreferenceSetting.kt new file mode 100644 index 00000000..cf400247 --- /dev/null +++ b/client/src/main/kotlin/preference/PreferenceSetting.kt @@ -0,0 +1,3 @@ +package preference + +object PreferenceSetting {} diff --git a/client/src/main/kotlin/screen/AchievementsDialog.kt b/client/src/main/kotlin/screen/AchievementsDialog.kt index 1ec3143a..ec088a4d 100644 --- a/client/src/main/kotlin/screen/AchievementsDialog.kt +++ b/client/src/main/kotlin/screen/AchievementsDialog.kt @@ -1,5 +1,6 @@ package screen +import achievement.Reward import achievement.getAchievementsEarned import bean.AchievementBadge import java.awt.Color @@ -36,25 +37,16 @@ class AchievementsDialog : JFrame(), MouseMotionListener, MouseListener, ActionL private val btnRight = JButton("\u25B6") private val testTube = JLabel("") - private val reward5: RewardStar = - RewardStar(5, "Four Colours", RewardDialog.REWARD_BANNER_FOUR_COLOUR) - private val reward10: RewardStar = - RewardStar(10, "Negative Jacks", RewardDialog.REWARD_BANNER_NEGATIVE_JACKS) - private val reward15: RewardStar = - RewardStar(15, "Blind Play", RewardDialog.REWARD_BANNER_BLIND) - private val reward20: RewardStar = - RewardStar(20, "New Deck Design", RewardDialog.REWARD_BANNER_MINIMALIST) - private val reward25: RewardStar = - RewardStar(25, "Vectropy", RewardDialog.REWARD_BANNER_VECTROPY) - private val reward30: RewardStar = - RewardStar(30, "Card Reveal", RewardDialog.REWARD_BANNER_CARD_REVEAL) - private val reward35: RewardStar = - RewardStar(35, "Extra Suits", RewardDialog.REWARD_BANNER_EXTRA_SUITS) - private val reward40: RewardStar = - RewardStar(40, "Illegal!", RewardDialog.REWARD_BANNER_ILLEGAL) - private val reward45: RewardStar = - RewardStar(45, "New Joker Design", RewardDialog.REWARD_BANNER_DEVELOPERS) - private val reward50: RewardStar = RewardStar(50, "Cheats", RewardDialog.REWARD_BANNER_CHEATS) + private val reward5: RewardStar = RewardStar("Four Colours", Reward.FourColours) + private val reward10: RewardStar = RewardStar("Negative Jacks", Reward.NegativeJacks) + private val reward15: RewardStar = RewardStar("Blind Play", Reward.Blind) + private val reward20: RewardStar = RewardStar("New Deck Design", Reward.MinimalistDeck) + private val reward25: RewardStar = RewardStar("Vectropy", Reward.Vectropy) + private val reward30: RewardStar = RewardStar("Card Reveal", Reward.CardReveal) + private val reward35: RewardStar = RewardStar("Extra Suits", Reward.ExtraSuits) + private val reward40: RewardStar = RewardStar("Illegal!", Reward.Illegal) + private val reward45: RewardStar = RewardStar("New Joker Design", Reward.DeveloperSet) + private val reward50: RewardStar = RewardStar("Cheats", Reward.Cheats) private val title = JLabel("") private val achievementName = JLabel("Achievement Name") @@ -250,7 +242,7 @@ class AchievementsDialog : JFrame(), MouseMotionListener, MouseListener, ActionL override fun mouseClicked(e: MouseEvent) { val c: RewardStar = e.component as RewardStar if (c.isUnlocked(getAchievementsEarned()) && !redrawing) { - RewardDialog.showDialog(c.imageName) + RewardDialog.showDialog(c.reward) } } diff --git a/client/src/main/kotlin/screen/HelpDialog.kt b/client/src/main/kotlin/screen/HelpDialog.kt index fad48e9f..302539c2 100644 --- a/client/src/main/kotlin/screen/HelpDialog.kt +++ b/client/src/main/kotlin/screen/HelpDialog.kt @@ -1,6 +1,7 @@ package screen import achievement.AchievementSetting +import achievement.Reward import achievement.isUnlocked import help.FundamentalsGlossary import help.FundamentalsTheDeck @@ -225,7 +226,7 @@ class HelpDialog : JFrame(), TreeSelectionListener, WindowListener, Registry { gameRules.add(entropyRules) } - if (Registry.rewards.getBoolean(Registry.REWARDS_BOOLEAN_VECTROPY, false)) { + if (Reward.Vectropy.isUnlocked()) { val vectropyRules = DefaultMutableTreeNode("Vectropy") addNodeBasedOnString(vectropyRules, rulesVectropyIntroduction, searchStr) addNodeBasedOnString(vectropyRules, rulesVectropyBidding, searchStr) @@ -236,7 +237,7 @@ class HelpDialog : JFrame(), TreeSelectionListener, WindowListener, Registry { } } - if (Registry.rewards.getBoolean(Registry.REWARDS_BOOLEAN_ILLEGAL, false)) { + if (Reward.Illegal.isUnlocked()) { addNodeBasedOnString(gameRules, rulesIllegal, searchStr) } @@ -262,7 +263,7 @@ class HelpDialog : JFrame(), TreeSelectionListener, WindowListener, Registry { addNodeBasedOnString(misc, miscBugReport, searchStr) addNodeBasedOnString(misc, miscClearingSaveData, searchStr) - if (Registry.rewards.getBoolean(Registry.REWARDS_BOOLEAN_CHEATS, false)) { + if (Reward.Cheats.isUnlocked()) { addNodeBasedOnString(misc, miscCheatCodes, searchStr) } diff --git a/client/src/main/kotlin/screen/preference/PreferencesDialog.kt b/client/src/main/kotlin/screen/preference/PreferencesDialog.kt new file mode 100644 index 00000000..70fb86e6 --- /dev/null +++ b/client/src/main/kotlin/screen/preference/PreferencesDialog.kt @@ -0,0 +1,81 @@ +package screen.preference + +import game.GameMode +import java.awt.BorderLayout +import javax.swing.BorderFactory +import javax.swing.JPanel +import javax.swing.JScrollPane +import javax.swing.JTabbedPane +import javax.swing.SwingConstants +import screen.AbstractPreferencesPanel +import screen.PreferencesPanelAppearance +import screen.PreferencesPanelGameplay +import screen.PreferencesPanelMisc +import screen.PreferencesPanelPlayers +import screen.SimpleDialog +import util.ApiUtil +import util.Registry +import utils.getAllChildComponentsForType + +class PreferencesDialog : SimpleDialog(), Registry { + private val tabbedPane = JTabbedPane(SwingConstants.TOP) + private val gameplayPanel = PreferencesPanelGameplay() + private val appearanceScrollPane = JScrollPane() + private val appearancePanel = PreferencesPanelAppearance() + private val playersPanel = PreferencesPanelPlayers() + private val miscPanel = PreferencesPanelMisc() + private val okCancelPanel = JPanel() + + init { + contentPane.setLayout(BorderLayout(0, 0)) + tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT) + contentPane.add(tabbedPane) + appearanceScrollPane.getVerticalScrollBar().setUnitIncrement(16) + tabbedPane.addTab("Gameplay", null, gameplayPanel, null) + tabbedPane.addTab("Players", null, playersPanel, null) + appearanceScrollPane.setViewportView(appearancePanel) + tabbedPane.addTab("Appearance", null, appearanceScrollPane, null) + tabbedPane.addTab("Miscellaneous", null, miscPanel, null) + contentPane.add(okCancelPanel, BorderLayout.SOUTH) + okCancelPanel.setBorder(BorderFactory.createEmptyBorder(10, 150, 10, 150)) + okCancelPanel.setLayout(BorderLayout(0, 0)) + okCancelPanel.add(btnOk, BorderLayout.WEST) + okCancelPanel.add(btnCancel, BorderLayout.EAST) + + childPanels().forEach { panel -> + panel.setParent(this) + panel.initVariables() + } + } + + private fun valid(): Boolean { + childPanels().forEach { panel -> + if (!panel.valid()) { + tabbedPane.selectedComponent = panel + return false + } + } + + return true + } + + fun gameModeChanged(gameMode: GameMode?) { + playersPanel.updateStrategySelection(gameMode) + } + + private fun childPanels() = getAllChildComponentsForType() + + override fun okPressed() { + childPanels().forEach { it.savePreferences() } + closeDialog() + } + + override fun cancelPressed() { + closeDialog() + } + + private fun closeDialog() { + ApiUtil.clearCache() + dispose() + } +} diff --git a/client/src/main/kotlin/util/ClientGlobals.kt b/client/src/main/kotlin/util/ClientGlobals.kt index 38a8e325..fd5e1e27 100644 --- a/client/src/main/kotlin/util/ClientGlobals.kt +++ b/client/src/main/kotlin/util/ClientGlobals.kt @@ -25,4 +25,6 @@ object ClientGlobals { var updateManager = UpdateManager() val webSocketReceiver = WebSocketReceiver() @JvmField var achievementStore: AbstractSettingStore = DefaultSettingStore("achievements") + @JvmField var preferenceStore: AbstractSettingStore = DefaultSettingStore("preferences") + @JvmField var rewardStore: AbstractSettingStore = DefaultSettingStore("rewards") } diff --git a/client/src/main/resources/rewards/rewardBlind.png b/client/src/main/resources/rewards/blind.png similarity index 100% rename from client/src/main/resources/rewards/rewardBlind.png rename to client/src/main/resources/rewards/blind.png diff --git a/client/src/main/resources/rewards/rewardCardReveal.png b/client/src/main/resources/rewards/cardReveal.png similarity index 100% rename from client/src/main/resources/rewards/rewardCardReveal.png rename to client/src/main/resources/rewards/cardReveal.png diff --git a/client/src/main/resources/rewards/rewardCheats.png b/client/src/main/resources/rewards/cheats.png similarity index 100% rename from client/src/main/resources/rewards/rewardCheats.png rename to client/src/main/resources/rewards/cheats.png diff --git a/client/src/main/resources/rewards/rewardDevelopers.png b/client/src/main/resources/rewards/developerSet.png similarity index 100% rename from client/src/main/resources/rewards/rewardDevelopers.png rename to client/src/main/resources/rewards/developerSet.png diff --git a/client/src/main/resources/rewards/rewardExtraSuits.png b/client/src/main/resources/rewards/extraSuits.png similarity index 100% rename from client/src/main/resources/rewards/rewardExtraSuits.png rename to client/src/main/resources/rewards/extraSuits.png diff --git a/client/src/main/resources/rewards/rewardFourColour.png b/client/src/main/resources/rewards/fourColours.png similarity index 100% rename from client/src/main/resources/rewards/rewardFourColour.png rename to client/src/main/resources/rewards/fourColours.png diff --git a/client/src/main/resources/rewards/rewardIllegal.png b/client/src/main/resources/rewards/illegal.png similarity index 100% rename from client/src/main/resources/rewards/rewardIllegal.png rename to client/src/main/resources/rewards/illegal.png diff --git a/client/src/main/resources/rewards/rewardMinimalist.png b/client/src/main/resources/rewards/minimalist.png similarity index 100% rename from client/src/main/resources/rewards/rewardMinimalist.png rename to client/src/main/resources/rewards/minimalist.png diff --git a/client/src/main/resources/rewards/rewardNegativeJacks.png b/client/src/main/resources/rewards/negativeJacks.png similarity index 100% rename from client/src/main/resources/rewards/rewardNegativeJacks.png rename to client/src/main/resources/rewards/negativeJacks.png diff --git a/client/src/main/resources/rewards/rewardVectropy.png b/client/src/main/resources/rewards/vectropy.png similarity index 100% rename from client/src/main/resources/rewards/rewardVectropy.png rename to client/src/main/resources/rewards/vectropy.png diff --git a/client/src/main/resources/update/update.bat b/client/src/main/resources/update/update.bat index 92f8a7b1..9310e1e1 100644 --- a/client/src/main/resources/update/update.bat +++ b/client/src/main/resources/update/update.bat @@ -7,11 +7,11 @@ REM %4 = assetId echo Performing download of %1 bytes (Version %2) -curl -LJO -H "Accept: application/octet-stream" https://api.github.com/repos/alyssaburlton/Dartzee/releases/assets/%4 +curl -LJO -H "Accept: application/octet-stream" https://api.github.com/repos/alyssaruth/Entropy/releases/assets/%4 -ren Dartzee.jar Dartzee_OLD.jar -ren %3 Dartzee.jar -del Dartzee_OLD.jar +ren Entropy.jar Entropy_OLD.jar +ren %3 Entropy.jar +del Entropy_OLD.jar -start javaw -Xms256m -Xmx512m -jar Dartzee.jar justUpdated trueLaunch +start javaw -Xms256m -Xmx512m -jar Entropy.jar justUpdated trueLaunch exit \ No newline at end of file diff --git a/core/src/main/java/util/Registry.java b/core/src/main/java/util/Registry.java index fd25d63b..40bb5522 100644 --- a/core/src/main/java/util/Registry.java +++ b/core/src/main/java/util/Registry.java @@ -11,7 +11,6 @@ public interface Registry //Actual preference wrappers public static final Preferences savedGame = Preferences.userRoot().node("entropySavedgameNone"); public static final Preferences prefs = Preferences.userRoot().node("entropyPreferencesTuuug"); - public static final Preferences rewards = Preferences.userRoot().node("entropyRewardsNone"); public static final Preferences inGameReplay = Preferences.userRoot().node("entropyReplayCurrent"); public static final Preferences fileReplay = Preferences.userRoot().node("entropyReplayFile"); public static final Preferences tempReplayStore = Preferences.userRoot().node("entropyTemp"); @@ -126,20 +125,6 @@ public interface Registry public static final String REPLAY_INT_PLAYER_WON = "playerWon"; public static final String REPLAY_INT_GAME_MODE = "gameMode"; - //rewards - public static final String REWARDS_BOOLEAN_FOUR_COLOURS = "fourColours"; - //public static final String REWARDS_BOOLEAN_JOKERS = "jokers"; - public static final String REWARDS_BOOLEAN_NEGATIVE_JACKS = "negativeJacks"; - public static final String REWARDS_BOOLEAN_MINIMALIST_DECK = "minimalist"; - public static final String REWARDS_BOOLEAN_BLIND = "blind"; - public static final String REWARDS_BOOLEAN_VECTROPY = "vectropy"; - //public static final String REWARDS_BOOLEAN_HANDICAP = "handicap"; - public static final String REWARDS_BOOLEAN_CARD_REVEAL = "cardReveal"; - public static final String REWARDS_BOOLEAN_DEVELOPER_JOKERS = "developerSet"; - public static final String REWARDS_BOOLEAN_ILLEGAL = "illegal"; - public static final String REWARDS_BOOLEAN_EXTRA_SUITS = "extraSuits"; - public static final String REWARDS_BOOLEAN_CHEATS = "cheats"; - //savedGame public static final String SAVED_GAME_STRING_RESULT_TEXT = "resultText"; public static final String SAVED_GAME_STRING_TOTAL_CARDS_LABEL = "totalCardsLabel"; From 0b096c5c4fdfb21812c13998c7816a1ed4a606fc Mon Sep 17 00:00:00 2001 From: alyssa Date: Sat, 23 Aug 2025 22:35:50 +0100 Subject: [PATCH 02/13] more reward tweaks/kotlinising --- client/src/main/java/object/RewardStar.java | 57 ------ .../src/main/java/screen/ClearDataDialog.java | 2 +- client/src/main/java/screen/MainScreen.java | 1 + client/src/main/java/screen/ReplayDialog.java | 1 + .../src/main/java/screen/ReplayInterface.java | 1 + client/src/main/java/screen/RewardDialog.java | 179 ------------------ .../kotlin/achievement/AchievementUtil.kt | 4 +- client/src/main/kotlin/screen/HelpDialog.kt | 1 + client/src/main/kotlin/screen/SimpleDialog.kt | 10 +- .../{ => achievement}/AchievementsDialog.kt | 67 +------ .../{ => achievement}/AchievementsPanel.kt | 2 +- .../kotlin/screen/achievement/RewardDialog.kt | 151 +++++++++++++++ .../kotlin/screen/achievement/RewardStar.kt | 56 ++++++ .../kotlin/achievement/AchievementUtilTest.kt | 2 +- .../AchievementsDialogTest.kt | 2 +- .../AchievementsPanelTest.kt | 2 +- 16 files changed, 229 insertions(+), 309 deletions(-) delete mode 100644 client/src/main/java/object/RewardStar.java delete mode 100644 client/src/main/java/screen/RewardDialog.java rename client/src/main/kotlin/screen/{ => achievement}/AchievementsDialog.kt (80%) rename client/src/main/kotlin/screen/{ => achievement}/AchievementsPanel.kt (95%) create mode 100644 client/src/main/kotlin/screen/achievement/RewardDialog.kt create mode 100644 client/src/main/kotlin/screen/achievement/RewardStar.kt rename client/src/test/kotlin/screen/{ => achievement}/AchievementsDialogTest.kt (98%) rename client/src/test/kotlin/screen/{ => achievement}/AchievementsPanelTest.kt (98%) diff --git a/client/src/main/java/object/RewardStar.java b/client/src/main/java/object/RewardStar.java deleted file mode 100644 index cfacad16..00000000 --- a/client/src/main/java/object/RewardStar.java +++ /dev/null @@ -1,57 +0,0 @@ -package object; - -import achievement.Reward; - -import javax.swing.Icon; -import javax.swing.JLabel; - -@SuppressWarnings("serial") -public class RewardStar extends JLabel -{ - private String hoverDesc; - private Reward reward; - - public RewardStar(String hoverDesc, Reward reward) - { - super(); - this.hoverDesc = hoverDesc; - this.reward = reward; - } - - public boolean isUnlocked(int achievementsEarned) - { - return achievementsEarned >= reward.getThreshold(); - } - - public String getHoverDesc() - { - return hoverDesc; - } - - public Reward getReward() - { - return reward; - } - - @Override - public void setIcon(Icon icon) - { - Icon currentIcon = getIcon(); - - if (currentIcon == null || !icon.equals(currentIcon)) - { - super.setIcon(icon); - } - } - - @Override - public void setToolTipText(String text) - { - String currentText = getToolTipText(); - - if (currentText == null || !text.equals(currentText)) - { - super.setToolTipText(text); - } - } -} diff --git a/client/src/main/java/screen/ClearDataDialog.java b/client/src/main/java/screen/ClearDataDialog.java index a7f354da..44b4c32c 100644 --- a/client/src/main/java/screen/ClearDataDialog.java +++ b/client/src/main/java/screen/ClearDataDialog.java @@ -1,6 +1,6 @@ package screen; -import achievement.AchievementSetting; +import screen.achievement.AchievementsDialog; import util.*; import javax.swing.*; diff --git a/client/src/main/java/screen/MainScreen.java b/client/src/main/java/screen/MainScreen.java index c4ae8f86..8d0098cd 100644 --- a/client/src/main/java/screen/MainScreen.java +++ b/client/src/main/java/screen/MainScreen.java @@ -12,6 +12,7 @@ import online.screen.TestHarness; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import screen.achievement.AchievementsDialog; import screen.preference.PreferencesDialog; import settings.Setting; import settings.SettingChangeListener; diff --git a/client/src/main/java/screen/ReplayDialog.java b/client/src/main/java/screen/ReplayDialog.java index 117413c5..1a25d46c 100644 --- a/client/src/main/java/screen/ReplayDialog.java +++ b/client/src/main/java/screen/ReplayDialog.java @@ -41,6 +41,7 @@ import object.PlayerLabel; import online.screen.GameRoom; import online.screen.OnlineChatPanel; +import screen.achievement.AchievementsDialog; import util.*; import static game.CardsUtilKt.countSuit; diff --git a/client/src/main/java/screen/ReplayInterface.java b/client/src/main/java/screen/ReplayInterface.java index 24bb0c79..4b70c5b3 100644 --- a/client/src/main/java/screen/ReplayInterface.java +++ b/client/src/main/java/screen/ReplayInterface.java @@ -4,6 +4,7 @@ import bean.FileUploadListener; import bean.FileUploader; import object.ReplayTable; +import screen.achievement.AchievementsDialog; import util.DialogUtil; import util.Registry; import util.ReplayFileUtil; diff --git a/client/src/main/java/screen/RewardDialog.java b/client/src/main/java/screen/RewardDialog.java deleted file mode 100644 index 7598310b..00000000 --- a/client/src/main/java/screen/RewardDialog.java +++ /dev/null @@ -1,179 +0,0 @@ -package screen; - -import achievement.Reward; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.BorderFactory; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextPane; -import javax.swing.SwingConstants; - -@SuppressWarnings("serial") -public class RewardDialog extends JDialog - implements ActionListener -{ - public RewardDialog(Reward reward) - { - topPanel.setLayout(new BorderLayout(0, 0)); - rewardTitle.setFont(new Font("Tahoma", Font.BOLD, 16)); - rewardTitle.setHorizontalAlignment(SwingConstants.CENTER); - rewardTitle.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); - topPanel.add(rewardTitle, BorderLayout.NORTH); - ImageIcon banner = new ImageIcon(getClass().getResource("/rewards/" + reward.getSettingName() + ".png")); - imageBanner.setHorizontalAlignment(SwingConstants.CENTER); - imageBanner.setIcon(banner); - topPanel.add(imageBanner, BorderLayout.SOUTH); - getContentPane().add(topPanel, BorderLayout.NORTH); - - setRewardDescriptionAndDialogSize(reward); - rewardDescription.setEditable(false); - rewardDescription.setOpaque(false); - rewardDescription.setBorder(BorderFactory.createEmptyBorder(15, 10, 10, 10)); - rewardDescription.setBackground(new Color(0, 0, 0, 0)); - getContentPane().add(rewardDescription, BorderLayout.CENTER); - - buttonPanel.add(btnOk); - getContentPane().add(buttonPanel, BorderLayout.SOUTH); - - btnOk.addActionListener(this); - } - - private final JLabel rewardTitle = new JLabel("Title"); - private final JLabel imageBanner = new JLabel(""); - private final JTextPane rewardDescription = new JTextPane(); - private final JPanel topPanel = new JPanel(); - private final JPanel buttonPanel = new JPanel(); - private final JButton btnOk = new JButton("Ok"); - - - public static void showDialog(Reward reward) - { - RewardDialog dialog = new RewardDialog(reward); - - dialog.setLocationRelativeTo(null); - dialog.setResizable(false); - dialog.setModal(true); - dialog.setVisible(true); - } - - - @Override - public void actionPerformed(ActionEvent arg0) - { - setVisible(false); - } - - private void setRewardDescriptionAndDialogSize(Reward reward) - { - String rewardStr = ""; - - if (reward == Reward.Blind) - { - rewardTitle.setText("Blind play unlocked!"); - rewardStr = "Ramp up the challenge by making decisions without looking at your cards!" - + "\n\nWith this option enabled, your cards will be dealt face-down by default. You can look at any time " - + "by clicking the eye but be warned: some achievements require you to go an entire game without peeking once!" - + "\n\nEnable this option by going to Tools > Preferences > Gameplay and ticking 'Play Blind'."; - - rewardDescription.setText(rewardStr); - setSize(new Dimension(400, 410)); - } - else if (reward == Reward.DeveloperSet) - { - rewardTitle.setText("'Developers' joker set unlocked!"); - rewardStr = "These jokers feature the faces of four people who helped to develop Entropy." - + "\n\nUse them by going to Tools > Preferences > Appearance and selecting 'Developers' as the Joker Design."; - - rewardDescription.setText(rewardStr); - setSize(new Dimension(400, 330)); - } - else if (reward == Reward.FourColours) - { - rewardTitle.setText("Four colour deck unlocked!"); - rewardStr = "You can now play with a four-colour deck, where clubs are green and diamonds are blue." - + "\n\nEnable this option by going to Tools > Preferences > Appearance and ticking 'Use 4 colour deck'."; - - rewardDescription.setText(rewardStr); - setSize(new Dimension(400, 330)); - } - else if (reward == Reward.CardReveal) - { - rewardTitle.setText("Card reveal unlocked!"); - rewardStr = "Add extra pressure to the game by forcing players to reveal their cards!" - + "\n\nWith this option set, players will be forced to show a card each time they make a bid. " - + "Players do not have to reveal their last card so not all cards will be shown." - + "\n\nEnable this option by going to Tools > Preferences > Gameplay and ticking 'Players reveal cards'."; - - rewardDescription.setText(rewardStr); - setSize(new Dimension(400, 390)); - } - else if (reward == Reward.NegativeJacks) - { - rewardTitle.setText("Negative jacks unlocked!"); - rewardStr = "Spice up the deck by makings Jacks worth -1 of their suit!" - + "\n\nEnable this option by going to Tools > Preferences > Gameplay and ticking 'Jacks worth -1'"; - - rewardDescription.setText(rewardStr); - setSize(new Dimension(400, 310)); - } - else if (reward == Reward.MinimalistDeck) - { - rewardTitle.setText("'Minimalist' deck design unlocked!"); - rewardStr = "Go for a more minimalist feel with this new deck design." - + "\n\nUse it by going to Tools > Preferences > Appearance and selecting 'Minimalist' as the Deck Design."; - - rewardDescription.setText(rewardStr); - setSize(new Dimension(400, 310)); - } - else if (reward == Reward.Vectropy) - { - rewardTitle.setText("Vectropy unlocked!"); - rewardStr = "Vectropy is a variant where you have to bid in all four suits at once. " - + "New help pages have been added that detail the rules for this new game." - + "\n\nPlay Vectropy by going to Tools > Preferences > Gameplay and selecting 'Vectropy' (under Game Mode)."; - - rewardDescription.setText(rewardStr); - setSize(new Dimension(400, 350)); - } - else if (reward == Reward.Illegal) - { - rewardTitle.setText("'Illegal' option unlocked!"); - rewardStr = "You can now shout 'Illegal!' in response to a bid that you think is perfect! " - + "\n\nIf you're right your opponent loses a card, but if you're wrong you'll lose one - even if a challenge would have been correct!" - + "\n\nYou will see the new 'Illegal!' option the next time you play a game."; - - rewardDescription.setText(rewardStr); - setSize(new Dimension(400, 370)); - } - else if (reward == Reward.ExtraSuits) - { - rewardTitle.setText("Extra suits unlocked!"); - rewardStr = "You can now play with Stars and Moons, making for up to 6 suits in total! " - + "\nSuit order remains alphabetical, making Stars the strongest suit if they are in play." - + "\n\nChoose which suits to play with by going to Tools > Preferences > Gameplay and using the options under 'Deck Setup'."; - - rewardDescription.setText(rewardStr); - setSize(new Dimension(400, 370)); - } - else if (reward == Reward.Cheats) - { - rewardTitle.setText("Cheats unlocked!"); - rewardStr = "Now you can use certain codes to cheat on your opponents, and even access hidden screens!" - + "\n\nThese were first created to speed up testing, especially for things that relied on being good - seriously, who has time for that?" - + "\n\nA full list of cheats can be found under Help > Miscellaneous > Cheat Codes."; - - rewardDescription.setText(rewardStr); - setSize(new Dimension(400, 390)); - } - } -} diff --git a/client/src/main/kotlin/achievement/AchievementUtil.kt b/client/src/main/kotlin/achievement/AchievementUtil.kt index c27e6e0a..817e2461 100644 --- a/client/src/main/kotlin/achievement/AchievementUtil.kt +++ b/client/src/main/kotlin/achievement/AchievementUtil.kt @@ -1,11 +1,11 @@ package achievement import javax.swing.ImageIcon -import screen.AchievementsDialog import screen.HelpDialog import screen.MainScreen -import screen.RewardDialog import screen.ScreenCache +import screen.achievement.AchievementsDialog +import screen.achievement.RewardDialog import settings.Setting import util.ClientGlobals import util.ClientGlobals.achievementStore diff --git a/client/src/main/kotlin/screen/HelpDialog.kt b/client/src/main/kotlin/screen/HelpDialog.kt index 302539c2..6544453d 100644 --- a/client/src/main/kotlin/screen/HelpDialog.kt +++ b/client/src/main/kotlin/screen/HelpDialog.kt @@ -43,6 +43,7 @@ import javax.swing.tree.TreeNode import javax.swing.tree.TreePath import javax.swing.tree.TreeSelectionModel import kotlin.math.max +import screen.achievement.AchievementsDialog import util.AchievementsUtil.UnlockAchievementTask import util.ClientGlobals.achievementStore import util.Registry diff --git a/client/src/main/kotlin/screen/SimpleDialog.kt b/client/src/main/kotlin/screen/SimpleDialog.kt index 9d2c79fd..0ecd1d19 100644 --- a/client/src/main/kotlin/screen/SimpleDialog.kt +++ b/client/src/main/kotlin/screen/SimpleDialog.kt @@ -8,7 +8,7 @@ import javax.swing.JDialog import javax.swing.JPanel import utils.CoreGlobals.logger -abstract class SimpleDialog : JDialog(), ActionListener { +abstract class SimpleDialog(includeCancel: Boolean = true) : JDialog(), ActionListener { protected val panelOkCancel = JPanel() protected val btnOk = JButton("Ok") protected val btnCancel = JButton("Cancel") @@ -19,10 +19,12 @@ abstract class SimpleDialog : JDialog(), ActionListener { isResizable = false panelOkCancel.add(btnOk) - panelOkCancel.add(btnCancel) - btnOk.addActionListener(this) - btnCancel.addActionListener(this) + + if (includeCancel) { + panelOkCancel.add(btnCancel) + btnCancel.addActionListener(this) + } } /** Abstract methods */ diff --git a/client/src/main/kotlin/screen/AchievementsDialog.kt b/client/src/main/kotlin/screen/achievement/AchievementsDialog.kt similarity index 80% rename from client/src/main/kotlin/screen/AchievementsDialog.kt rename to client/src/main/kotlin/screen/achievement/AchievementsDialog.kt index ec088a4d..17798c0f 100644 --- a/client/src/main/kotlin/screen/AchievementsDialog.kt +++ b/client/src/main/kotlin/screen/achievement/AchievementsDialog.kt @@ -1,4 +1,4 @@ -package screen +package screen.achievement import achievement.Reward import achievement.getAchievementsEarned @@ -8,9 +8,9 @@ import java.awt.Font import java.awt.event.ActionEvent import java.awt.event.ActionListener import java.awt.event.MouseEvent -import java.awt.event.MouseListener import java.awt.event.MouseMotionListener -import java.util.* +import java.util.Timer +import java.util.TimerTask import javax.swing.ImageIcon import javax.swing.JButton import javax.swing.JFrame @@ -19,11 +19,9 @@ import javax.swing.JPanel import javax.swing.JSeparator import javax.swing.SwingConstants import javax.swing.border.EmptyBorder -import `object`.RewardStar -import util.Images import utils.getAllChildComponentsForType -class AchievementsDialog : JFrame(), MouseMotionListener, MouseListener, ActionListener { +class AchievementsDialog : JFrame(), MouseMotionListener, ActionListener { private var currentPage = 0 private var progressShowing = 0 @@ -129,7 +127,6 @@ class AchievementsDialog : JFrame(), MouseMotionListener, MouseListener, ActionL } populateBadgeListAndAddMotionListeners() - populateStarListAndAddMouseListeners() } fun init() { @@ -145,10 +142,6 @@ class AchievementsDialog : JFrame(), MouseMotionListener, MouseListener, ActionL getAllChildComponentsForType().forEach { it.addMouseMotionListener(this) } } - private fun populateStarListAndAddMouseListeners() { - getAllChildComponentsForType().forEach { it.addMouseListener(this) } - } - private fun animateTestTube() { redrawing = true @@ -164,7 +157,6 @@ class AchievementsDialog : JFrame(), MouseMotionListener, MouseListener, ActionL private fun updateTestTube() { progressShowing = getAchievementsEarned() testTube.icon = getTubeIconForIndex(getAchievementsEarned()) - redrawStars() } private fun getTubeIconForIndex(i: Int): ImageIcon { @@ -172,20 +164,6 @@ class AchievementsDialog : JFrame(), MouseMotionListener, MouseListener, ActionL return ImageIcon(AchievementsDialog::class.java.getResource("/tubes/$name")) } - private fun redrawStars() { - getAllChildComponentsForType().forEach { star -> - if (star.isUnlocked(getAchievementsEarned())) { - star.setIcon(Images.REWARD_UNLOCKED) - star.setToolTipText(star.hoverDesc) - } else { - star.setIcon(Images.REWARD_LOCKED) - star.setToolTipText("Locked") - } - - star.repaint() - } - } - fun refresh(restartTube: Boolean) { if (restartTube) { animateTestTube() @@ -193,6 +171,7 @@ class AchievementsDialog : JFrame(), MouseMotionListener, MouseListener, ActionL updateTestTube() } + getAllChildComponentsForType().forEach { it.toggle() } getAllChildComponentsForType().forEach { it.toggle() } updateTitle() @@ -230,7 +209,6 @@ class AchievementsDialog : JFrame(), MouseMotionListener, MouseListener, ActionL } testTube.icon = getTubeIconForIndex(progressShowing) - redrawStars() if (progressShowing == getAchievementsEarned()) { redrawing = false @@ -239,41 +217,6 @@ class AchievementsDialog : JFrame(), MouseMotionListener, MouseListener, ActionL } } - override fun mouseClicked(e: MouseEvent) { - val c: RewardStar = e.component as RewardStar - if (c.isUnlocked(getAchievementsEarned()) && !redrawing) { - RewardDialog.showDialog(c.reward) - } - } - - override fun mouseEntered(e: MouseEvent) { - val source: RewardStar = e.component as RewardStar - if (source.isUnlocked(progressShowing) && !redrawing) { - source.setIcon(Images.REWARD_UNLOCKED_HOVERED) - } - } - - override fun mouseExited(e: MouseEvent) { - val source: RewardStar = e.component as RewardStar - if (source.isUnlocked(progressShowing) && !redrawing) { - source.setIcon(Images.REWARD_UNLOCKED) - } - } - - override fun mousePressed(e: MouseEvent) { - val source: RewardStar = e.component as RewardStar - if (source.isUnlocked(getAchievementsEarned()) && !redrawing) { - source.setIcon(Images.REWARD_UNLOCKED_CLICKED) - } - } - - override fun mouseReleased(e: MouseEvent) { - val source: RewardStar = e.component as RewardStar - if (source.isUnlocked(getAchievementsEarned()) && !redrawing) { - source.setIcon(Images.REWARD_UNLOCKED) - } - } - override fun actionPerformed(arg0: ActionEvent) { if (arg0.source === btnLeft) { currentPage-- diff --git a/client/src/main/kotlin/screen/AchievementsPanel.kt b/client/src/main/kotlin/screen/achievement/AchievementsPanel.kt similarity index 95% rename from client/src/main/kotlin/screen/AchievementsPanel.kt rename to client/src/main/kotlin/screen/achievement/AchievementsPanel.kt index 49f6bb8c..d27885ba 100644 --- a/client/src/main/kotlin/screen/AchievementsPanel.kt +++ b/client/src/main/kotlin/screen/achievement/AchievementsPanel.kt @@ -1,4 +1,4 @@ -package screen +package screen.achievement import bean.AchievementBadge import javax.swing.JPanel diff --git a/client/src/main/kotlin/screen/achievement/RewardDialog.kt b/client/src/main/kotlin/screen/achievement/RewardDialog.kt new file mode 100644 index 00000000..d0939cef --- /dev/null +++ b/client/src/main/kotlin/screen/achievement/RewardDialog.kt @@ -0,0 +1,151 @@ +package screen.achievement + +import achievement.Reward +import java.awt.BorderLayout +import java.awt.Color +import java.awt.Dimension +import java.awt.Font +import javax.swing.BorderFactory +import javax.swing.ImageIcon +import javax.swing.JLabel +import javax.swing.JPanel +import javax.swing.JTextPane +import javax.swing.SwingConstants +import screen.SimpleDialog + +class RewardDialog(reward: Reward) : SimpleDialog(false) { + private val rewardTitle = JLabel("Title") + private val imageBanner = JLabel("") + private val rewardDescription = JTextPane() + private val topPanel = JPanel() + private val buttonPanel = JPanel() + + init { + topPanel.setLayout(BorderLayout(0, 0)) + rewardTitle.setFont(Font("Tahoma", Font.BOLD, 16)) + rewardTitle.setHorizontalAlignment(SwingConstants.CENTER) + rewardTitle.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)) + topPanel.add(rewardTitle, BorderLayout.NORTH) + val banner = ImageIcon(javaClass.getResource("/rewards/${reward.settingName}.png")) + imageBanner.setHorizontalAlignment(SwingConstants.CENTER) + imageBanner.setIcon(banner) + topPanel.add(imageBanner, BorderLayout.SOUTH) + contentPane.add(topPanel, BorderLayout.NORTH) + + setRewardDescriptionAndDialogSize(reward) + rewardDescription.setEditable(false) + rewardDescription.setOpaque(false) + rewardDescription.setBorder(BorderFactory.createEmptyBorder(15, 10, 10, 10)) + rewardDescription.setBackground(Color(0, 0, 0, 0)) + contentPane.add(rewardDescription, BorderLayout.CENTER) + + buttonPanel.add(btnOk) + contentPane.add(buttonPanel, BorderLayout.SOUTH) + } + + override fun okPressed() { + dispose() + } + + private fun setRewardDescriptionAndDialogSize(reward: Reward) { + var rewardStr = "" + + if (reward == Reward.Blind) { + rewardTitle.setText("Blind play unlocked!") + rewardStr = + ("Ramp up the challenge by making decisions without looking at your cards!" + + "\n\nWith this option enabled, your cards will be dealt face-down by default. You can look at any time " + + "by clicking the eye but be warned: some achievements require you to go an entire game without peeking once!" + + "\n\nEnable this option by going to Tools > Preferences > Gameplay and ticking 'Play Blind'.") + + rewardDescription.setText(rewardStr) + size = Dimension(400, 410) + } else if (reward == Reward.DeveloperSet) { + rewardTitle.setText("'Developers' joker set unlocked!") + rewardStr = + ("These jokers feature the faces of four people who helped to develop Entropy." + + "\n\nUse them by going to Tools > Preferences > Appearance and selecting 'Developers' as the Joker Design.") + + rewardDescription.setText(rewardStr) + size = Dimension(400, 330) + } else if (reward == Reward.FourColours) { + rewardTitle.setText("Four colour deck unlocked!") + rewardStr = + ("You can now play with a four-colour deck, where clubs are green and diamonds are blue." + + "\n\nEnable this option by going to Tools > Preferences > Appearance and ticking 'Use 4 colour deck'.") + + rewardDescription.setText(rewardStr) + size = Dimension(400, 330) + } else if (reward == Reward.CardReveal) { + rewardTitle.setText("Card reveal unlocked!") + rewardStr = + ("Add extra pressure to the game by forcing players to reveal their cards!" + + "\n\nWith this option set, players will be forced to show a card each time they make a bid. " + + "Players do not have to reveal their last card so not all cards will be shown." + + "\n\nEnable this option by going to Tools > Preferences > Gameplay and ticking 'Players reveal cards'.") + + rewardDescription.setText(rewardStr) + size = Dimension(400, 390) + } else if (reward == Reward.NegativeJacks) { + rewardTitle.setText("Negative jacks unlocked!") + rewardStr = + ("Spice up the deck by makings Jacks worth -1 of their suit!" + + "\n\nEnable this option by going to Tools > Preferences > Gameplay and ticking 'Jacks worth -1'") + + rewardDescription.setText(rewardStr) + size = Dimension(400, 310) + } else if (reward == Reward.MinimalistDeck) { + rewardTitle.setText("'Minimalist' deck design unlocked!") + rewardStr = + ("Go for a more minimalist feel with this new deck design." + + "\n\nUse it by going to Tools > Preferences > Appearance and selecting 'Minimalist' as the Deck Design.") + + rewardDescription.setText(rewardStr) + size = Dimension(400, 310) + } else if (reward == Reward.Vectropy) { + rewardTitle.setText("Vectropy unlocked!") + rewardStr = + ("Vectropy is a variant where you have to bid in all four suits at once. " + + "New help pages have been added that detail the rules for this new game." + + "\n\nPlay Vectropy by going to Tools > Preferences > Gameplay and selecting 'Vectropy' (under Game Mode).") + + rewardDescription.setText(rewardStr) + size = Dimension(400, 350) + } else if (reward == Reward.Illegal) { + rewardTitle.setText("'Illegal' option unlocked!") + rewardStr = + ("You can now shout 'Illegal!' in response to a bid that you think is perfect! " + + "\n\nIf you're right your opponent loses a card, but if you're wrong you'll lose one - even if a challenge would have been correct!" + + "\n\nYou will see the new 'Illegal!' option the next time you play a game.") + + rewardDescription.setText(rewardStr) + size = Dimension(400, 370) + } else if (reward == Reward.ExtraSuits) { + rewardTitle.setText("Extra suits unlocked!") + rewardStr = + ("You can now play with Stars and Moons, making for up to 6 suits in total! " + + "\nSuit order remains alphabetical, making Stars the strongest suit if they are in play." + + "\n\nChoose which suits to play with by going to Tools > Preferences > Gameplay and using the options under 'Deck Setup'.") + + rewardDescription.setText(rewardStr) + size = Dimension(400, 370) + } else if (reward == Reward.Cheats) { + rewardTitle.setText("Cheats unlocked!") + rewardStr = + ("Now you can use certain codes to cheat on your opponents, and even access hidden screens!" + + "\n\nThese were first created to speed up testing, especially for things that relied on being good - seriously, who has time for that?" + + "\n\nA full list of cheats can be found under Help > Miscellaneous > Cheat Codes.") + + rewardDescription.setText(rewardStr) + size = Dimension(400, 390) + } + } + + companion object { + fun showDialog(reward: Reward) { + val dialog = RewardDialog(reward) + dialog.setLocationRelativeTo(null) + dialog.isVisible = true + } + } +} diff --git a/client/src/main/kotlin/screen/achievement/RewardStar.kt b/client/src/main/kotlin/screen/achievement/RewardStar.kt new file mode 100644 index 00000000..5c6516eb --- /dev/null +++ b/client/src/main/kotlin/screen/achievement/RewardStar.kt @@ -0,0 +1,56 @@ +package screen.achievement + +import achievement.Reward +import java.awt.event.MouseEvent +import java.awt.event.MouseListener +import javax.swing.JLabel +import util.Images + +class RewardStar(val hoverDesc: String, val reward: Reward) : JLabel(), MouseListener { + + init { + addMouseListener(this) + } + + fun toggle() { + if (reward.isUnlocked()) { + setIcon(Images.REWARD_UNLOCKED) + toolTipText = hoverDesc + } else { + setIcon(Images.REWARD_LOCKED) + toolTipText = "Locked" + } + + repaint() + } + + override fun mouseClicked(e: MouseEvent?) { + if (reward.isUnlocked()) { + RewardDialog.showDialog(reward) + } + } + + override fun mousePressed(e: MouseEvent?) { + if (reward.isUnlocked()) { + setIcon(Images.REWARD_UNLOCKED_CLICKED) + } + } + + override fun mouseReleased(e: MouseEvent?) { + if (reward.isUnlocked()) { + setIcon(Images.REWARD_UNLOCKED) + } + } + + override fun mouseEntered(e: MouseEvent?) { + if (reward.isUnlocked()) { + setIcon(Images.REWARD_UNLOCKED_HOVERED) + } + } + + override fun mouseExited(e: MouseEvent?) { + if (reward.isUnlocked()) { + setIcon(Images.REWARD_UNLOCKED) + } + } +} diff --git a/client/src/test/kotlin/achievement/AchievementUtilTest.kt b/client/src/test/kotlin/achievement/AchievementUtilTest.kt index 5b2d8a2a..ce643e66 100644 --- a/client/src/test/kotlin/achievement/AchievementUtilTest.kt +++ b/client/src/test/kotlin/achievement/AchievementUtilTest.kt @@ -9,9 +9,9 @@ import io.mockk.verify import javax.swing.ImageIcon import javax.swing.JLabel import org.junit.jupiter.api.Test -import screen.AchievementsDialog import screen.MainScreen import screen.ScreenCache +import screen.achievement.AchievementsDialog import settings.Setting import testCore.verifyNotCalled import util.AbstractClientTest diff --git a/client/src/test/kotlin/screen/AchievementsDialogTest.kt b/client/src/test/kotlin/screen/achievement/AchievementsDialogTest.kt similarity index 98% rename from client/src/test/kotlin/screen/AchievementsDialogTest.kt rename to client/src/test/kotlin/screen/achievement/AchievementsDialogTest.kt index 29750fd7..8723c1fc 100644 --- a/client/src/test/kotlin/screen/AchievementsDialogTest.kt +++ b/client/src/test/kotlin/screen/achievement/AchievementsDialogTest.kt @@ -1,4 +1,4 @@ -package screen +package screen.achievement import achievement.unlockAchievement import bean.AchievementBadge diff --git a/client/src/test/kotlin/screen/AchievementsPanelTest.kt b/client/src/test/kotlin/screen/achievement/AchievementsPanelTest.kt similarity index 98% rename from client/src/test/kotlin/screen/AchievementsPanelTest.kt rename to client/src/test/kotlin/screen/achievement/AchievementsPanelTest.kt index b21d569b..078f0d3b 100644 --- a/client/src/test/kotlin/screen/AchievementsPanelTest.kt +++ b/client/src/test/kotlin/screen/achievement/AchievementsPanelTest.kt @@ -1,4 +1,4 @@ -package screen +package screen.achievement import bean.AchievementBadge import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder From 90a0b89f7b94d8ecf836593db3bcb66ad309a261 Mon Sep 17 00:00:00 2001 From: alyssa Date: Sat, 23 Aug 2025 23:06:47 +0100 Subject: [PATCH 03/13] more reward bits --- .../kotlin/achievement/AchievementUtil.kt | 6 +-- client/src/main/kotlin/achievement/Reward.kt | 9 +++- .../kotlin/screen/achievement/RewardDialog.kt | 4 +- .../src/test/kotlin/achievement/RewardTest.kt | 48 +++++++++++++++++++ .../test/kotlin/screen/SimpleDialogTest.kt | 15 +++++- .../test/kotlin/util/AbstractClientTest.kt | 1 + 6 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 client/src/test/kotlin/achievement/RewardTest.kt diff --git a/client/src/main/kotlin/achievement/AchievementUtil.kt b/client/src/main/kotlin/achievement/AchievementUtil.kt index 817e2461..deb00035 100644 --- a/client/src/main/kotlin/achievement/AchievementUtil.kt +++ b/client/src/main/kotlin/achievement/AchievementUtil.kt @@ -46,10 +46,8 @@ fun unlockAchievement(achievement: Achievement) { fun unlockRewards(achievementsEarned: Int) { Reward.entries.forEach { reward -> - if ( - achievementsEarned >= reward.threshold && !ClientGlobals.rewardStore.get(reward.setting) - ) { - ClientGlobals.rewardStore.save(reward.setting, true) + if (achievementsEarned >= reward.threshold && !reward.isUnlocked()) { + reward.unlock() RewardDialog.showDialog(reward) } } diff --git a/client/src/main/kotlin/achievement/Reward.kt b/client/src/main/kotlin/achievement/Reward.kt index 12604849..a57c5f25 100644 --- a/client/src/main/kotlin/achievement/Reward.kt +++ b/client/src/main/kotlin/achievement/Reward.kt @@ -1,5 +1,6 @@ package achievement +import java.net.URL import settings.Setting import util.ClientGlobals @@ -15,7 +16,13 @@ enum class Reward(val settingName: String, val threshold: Int) { DeveloperSet("developerSet", 45), Cheats("cheats", 50); - val setting: Setting = Setting(settingName, false) + private val setting: Setting = Setting(settingName, false) fun isUnlocked() = ClientGlobals.rewardStore.get(setting) + + fun unlock() { + ClientGlobals.rewardStore.save(setting, true) + } + + fun getResource(): URL? = javaClass.getResource("/rewards/$settingName.png") } diff --git a/client/src/main/kotlin/screen/achievement/RewardDialog.kt b/client/src/main/kotlin/screen/achievement/RewardDialog.kt index d0939cef..05069dc1 100644 --- a/client/src/main/kotlin/screen/achievement/RewardDialog.kt +++ b/client/src/main/kotlin/screen/achievement/RewardDialog.kt @@ -26,7 +26,7 @@ class RewardDialog(reward: Reward) : SimpleDialog(false) { rewardTitle.setHorizontalAlignment(SwingConstants.CENTER) rewardTitle.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)) topPanel.add(rewardTitle, BorderLayout.NORTH) - val banner = ImageIcon(javaClass.getResource("/rewards/${reward.settingName}.png")) + val banner = ImageIcon(reward.getResource()) imageBanner.setHorizontalAlignment(SwingConstants.CENTER) imageBanner.setIcon(banner) topPanel.add(imageBanner, BorderLayout.SOUTH) @@ -48,7 +48,7 @@ class RewardDialog(reward: Reward) : SimpleDialog(false) { } private fun setRewardDescriptionAndDialogSize(reward: Reward) { - var rewardStr = "" + var rewardStr: String if (reward == Reward.Blind) { rewardTitle.setText("Blind play unlocked!") diff --git a/client/src/test/kotlin/achievement/RewardTest.kt b/client/src/test/kotlin/achievement/RewardTest.kt new file mode 100644 index 00000000..57f4e8ad --- /dev/null +++ b/client/src/test/kotlin/achievement/RewardTest.kt @@ -0,0 +1,48 @@ +package achievement + +import io.kotest.assertions.withClue +import io.kotest.matchers.collections.shouldContainExactly +import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.nulls.shouldNotBeNull +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test +import settings.Setting +import util.AbstractClientTest +import util.ClientGlobals + +class RewardTest : AbstractClientTest() { + @Test + fun `Should be increasing order by unlock threshold`() { + val sorted = Reward.entries.sortedBy { it.threshold } + Reward.entries shouldContainExactly sorted + } + + @Test + fun `Thresholds should be distinct`() { + val groups = Reward.entries.groupBy { it.threshold } + groups.forEach { threshold, rewards -> + withClue("should only be 1 reward with threshold $threshold") { + rewards.shouldHaveSize(1) + } + } + } + + @Test + fun `Image assets should exist`() { + Reward.entries.forEach { reward -> + withClue("asset ${reward.settingName}.png should exist") { + reward.getResource().shouldNotBeNull() + } + } + } + + @Test + fun `Should report whether its unlocked or not`() { + Reward.NegativeJacks.isUnlocked() shouldBe false + + Reward.NegativeJacks.unlock() + + Reward.NegativeJacks.isUnlocked() shouldBe true + ClientGlobals.rewardStore.get(Setting("negativeJacks", false)) shouldBe true + } +} diff --git a/client/src/test/kotlin/screen/SimpleDialogTest.kt b/client/src/test/kotlin/screen/SimpleDialogTest.kt index f883bbef..9145ae17 100644 --- a/client/src/test/kotlin/screen/SimpleDialogTest.kt +++ b/client/src/test/kotlin/screen/SimpleDialogTest.kt @@ -2,7 +2,9 @@ package screen import com.github.alyssaburlton.swingtest.clickCancel import com.github.alyssaburlton.swingtest.clickOk +import com.github.alyssaburlton.swingtest.findChild import io.kotest.matchers.shouldBe +import javax.swing.AbstractButton import org.junit.jupiter.api.Test import testCore.AbstractTest import testCore.logger @@ -27,7 +29,18 @@ class SimpleDialogTest : AbstractTest() { verifyLog("ok.pressed") } - inner class SimpleDialogTestExtension : SimpleDialog() { + @Test + fun `Can exclude cancel button`() { + val dlg = SimpleDialogTestExtension(false) + dlg.findChild(text = "Cancel") shouldBe null + } + + inner class SimpleDialogTestExtension(includeCancel: Boolean = true) : + SimpleDialog(includeCancel) { + init { + isModal = false + } + override fun okPressed() { logger.info("ok.pressed", "pressed ok") } diff --git a/client/src/test/kotlin/util/AbstractClientTest.kt b/client/src/test/kotlin/util/AbstractClientTest.kt index a699780a..01d9e154 100644 --- a/client/src/test/kotlin/util/AbstractClientTest.kt +++ b/client/src/test/kotlin/util/AbstractClientTest.kt @@ -12,6 +12,7 @@ abstract class AbstractClientTest : AbstractTest() { @BeforeEach fun beforeEach() { ClientGlobals.achievementStore = InMemorySettingStore() + ClientGlobals.rewardStore = InMemorySettingStore() ScreenCache.emptyCache() } From 07eddf52164f6c7dd8513a196b425514f8383602 Mon Sep 17 00:00:00 2001 From: alyssa Date: Sat, 23 Aug 2025 23:12:43 +0100 Subject: [PATCH 04/13] fix more modality test rubbish --- client/src/main/kotlin/game/StrategyUtil.kt | 1 - client/src/test/kotlin/screen/online/PlayOnlineDialogTest.kt | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/client/src/main/kotlin/game/StrategyUtil.kt b/client/src/main/kotlin/game/StrategyUtil.kt index ad2451ec..f081e3bd 100644 --- a/client/src/main/kotlin/game/StrategyUtil.kt +++ b/client/src/main/kotlin/game/StrategyUtil.kt @@ -89,7 +89,6 @@ fun getBasicVectropyOpening( val map = suits.associateWith { suit -> val myCount = countSuit(suit, hand, settings.jokerValue) - println(myCount) maxOf(0, myCount + random.nextInt(3) - 1) } diff --git a/client/src/test/kotlin/screen/online/PlayOnlineDialogTest.kt b/client/src/test/kotlin/screen/online/PlayOnlineDialogTest.kt index ff809f36..08d47ca4 100644 --- a/client/src/test/kotlin/screen/online/PlayOnlineDialogTest.kt +++ b/client/src/test/kotlin/screen/online/PlayOnlineDialogTest.kt @@ -19,7 +19,7 @@ import util.ClientGlobals class PlayOnlineDialogTest : AbstractTest() { @Test fun `Should not allow an empty name`() { - val dlg = PlayOnlineDialog() + val dlg = PlayOnlineDialog().also { it.isModal = false } dlg.isVisible = true dlg.clickOk(async = true) @@ -32,7 +32,7 @@ class PlayOnlineDialogTest : AbstractTest() { fun `Should invoke the session API`() { ClientGlobals.sessionApi = mockk(relaxed = true) - val dlg = PlayOnlineDialog() + val dlg = PlayOnlineDialog().also { it.isModal = false } dlg.isVisible = true dlg.getChild().text = "Alyssa" dlg.clickOk() From 025b94f79a8b0676474a55d2430db8e6264e2939 Mon Sep 17 00:00:00 2001 From: alyssa Date: Mon, 25 Aug 2025 17:39:07 +0100 Subject: [PATCH 05/13] port most preferences to setting store abstraction --- client/src/main/java/EntropyMain.java | 9 +- .../main/java/object/BidListCellRenderer.java | 73 --- client/src/main/java/object/CardLabel.java | 20 +- client/src/main/java/object/ReplayTable.java | 15 +- .../src/main/java/online/screen/GameRoom.java | 7 +- .../java/online/util/ResponseHandler.java | 4 +- .../java/screen/AbstractPreferencesPanel.java | 3 +- .../src/main/java/screen/ClearDataDialog.java | 16 +- .../java/screen/ConfigureColumnsDialog.java | 25 +- .../src/main/java/screen/EntropyBidPanel.java | 17 +- .../src/main/java/screen/EntropyScreen.java | 4 +- client/src/main/java/screen/GameScreen.java | 31 +- client/src/main/java/screen/HandPanelMk2.java | 10 +- client/src/main/java/screen/MainScreen.java | 12 +- .../screen/PreferencesPanelAppearance.java | 72 +-- .../java/screen/PreferencesPanelGameplay.java | 25 +- .../java/screen/PreferencesPanelMisc.java | 59 +- .../java/screen/PreferencesPanelPlayers.java | 42 +- client/src/main/java/screen/ReplayDialog.java | 523 +++++++++--------- .../src/main/java/screen/ReplayInterface.java | 9 +- .../main/java/screen/VectropyBidPanel.java | 16 +- .../src/main/java/screen/VectropyScreen.java | 4 +- .../src/main/java/util/AchievementsUtil.java | 2 +- client/src/main/java/util/ApiUtil.java | 17 +- .../src/main/java/util/ReplayConverter.java | 8 - client/src/main/java/util/ReplayFileUtil.java | 8 +- .../src/main/kotlin/bean/AchievementBadge.kt | 3 +- .../main/kotlin/bean/BidListCellRenderer.kt | 67 +++ client/src/main/kotlin/game/RenderingUtil.kt | 20 + client/src/main/kotlin/help/HelpPanel.kt | 7 +- .../kotlin/preference/PreferenceSetting.kt | 65 ++- .../screen/preference/PreferencesDialog.kt | 3 +- .../kotlin/settings/AbstractSettingStore.kt | 4 +- .../test/kotlin/util/AbstractClientTest.kt | 1 + core/src/main/java/util/Registry.java | 46 -- core/src/main/kotlin/game/EntropyBidAction.kt | 3 - core/src/main/kotlin/game/PlayerAction.kt | 2 - core/src/main/kotlin/game/Suit.kt | 10 - .../test/kotlin/game/EntropyBidActionTest.kt | 5 - .../test/kotlin/game/VectropyBidActionTest.kt | 1 - 40 files changed, 645 insertions(+), 623 deletions(-) delete mode 100644 client/src/main/java/object/BidListCellRenderer.java create mode 100644 client/src/main/kotlin/bean/BidListCellRenderer.kt diff --git a/client/src/main/java/EntropyMain.java b/client/src/main/java/EntropyMain.java index 018f1384..872a0ce2 100644 --- a/client/src/main/java/EntropyMain.java +++ b/client/src/main/java/EntropyMain.java @@ -5,10 +5,13 @@ import javax.swing.WindowConstants; import logging.LoggerUncaughtExceptionHandler; +import preference.PreferenceSetting; import screen.MainScreen; import screen.ScreenCache; import util.*; +import static preference.PreferenceSettingKt.getPreference; +import static util.ClientGlobals.preferenceStore; import static utils.CoreGlobals.logger; public class EntropyMain implements Registry @@ -59,7 +62,7 @@ private static void setLookAndFeel() String lookAndFeel = null; try { - lookAndFeel = prefs.get(PREFERENCES_STRING_LOOK_AND_FEEL, "Metal"); + lookAndFeel = getPreference(PreferenceSetting.LookAndFeel); if (ClientUtil.isAppleOs() && lookAndFeel.equals("Metal")) { @@ -80,7 +83,7 @@ private static void setLookAndFeel() { logger.warn("laf.failed", "Failed to load LookAndFeel " + lookAndFeel + ". Caught " + e); DialogUtil.showError("Failed to load Look & Feel '" + lookAndFeel + "'. \nEntropy will use the default instead."); - prefs.put(PREFERENCES_STRING_LOOK_AND_FEEL, "Metal"); + preferenceStore.delete(PreferenceSetting.LookAndFeel); } } @@ -116,7 +119,7 @@ private static boolean bindOnPort(int portNumber) private static void checkForUpdatesIfRequired() { - boolean checkForUpdates = Registry.prefs.getBoolean(PREFERENCES_BOOLEAN_CHECK_FOR_UPDATES, true); + boolean checkForUpdates = getPreference(PreferenceSetting.CheckForUpdates); if (!checkForUpdates || ClientUtil.devMode) { diff --git a/client/src/main/java/object/BidListCellRenderer.java b/client/src/main/java/object/BidListCellRenderer.java deleted file mode 100644 index 4da78c8c..00000000 --- a/client/src/main/java/object/BidListCellRenderer.java +++ /dev/null @@ -1,73 +0,0 @@ -package object; - -import game.BidAction; -import game.PlayerAction; -import util.StringUtil; - -import java.awt.Component; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import javax.swing.DefaultListCellRenderer; -import javax.swing.JList; - -import static game.RenderingUtilKt.getCardHtml; -import static game.SuitKt.MOONS_SYMBOL; -import static utils.ColourUtilKt.getColourForPlayerNumber; - -public class BidListCellRenderer extends DefaultListCellRenderer -{ - private Map hmNameToColour = new HashMap<>(); - - @Override - public Component getListCellRendererComponent(JList list, Object value, - int index, boolean isSelected, boolean cellHasFocus) - { - PlayerAction bid = (PlayerAction)value; - String text = toHtmlString(bid); - - return super.getListCellRendererComponent(list, text, index, isSelected, - cellHasFocus); - } - - public void updateColours(Collection players) { - this.hmNameToColour.clear(); - - for (Player player : players) { - hmNameToColour.put(player.getName(), player.getColour()); - } - } - - public void updateColours(Map map) { - this.hmNameToColour = map; - } - - public String toHtmlString(PlayerAction action) - { - String playerName = action.getPlayerName(); - playerName = StringUtil.escapeHtml(playerName); - - String colour = hmNameToColour.get(playerName); - String playerNamePrefix = playerName + ": "; - - if (action.getBlind()) - { - playerNamePrefix = "[" + playerName + "]: "; - } - - String text = "" + playerNamePrefix; - text += ""; - text += action.htmlString(); - - if (action instanceof BidAction bid && bid.getCardToReveal() != null) { - text += "&emsp(Shows: "; - text += getCardHtml(bid.getCardToReveal()); - text += ")"; - } - - //The unicode for a moon doesn't work in HTML. Also shrink to match the size of the other suits. - text = text.replaceAll(MOONS_SYMBOL, "🌙"); - return text; - } -} diff --git a/client/src/main/java/object/CardLabel.java b/client/src/main/java/object/CardLabel.java index 9fe48c1d..650506f4 100644 --- a/client/src/main/java/object/CardLabel.java +++ b/client/src/main/java/object/CardLabel.java @@ -3,12 +3,14 @@ import javax.swing.ImageIcon; import javax.swing.JLabel; +import preference.PreferenceSetting; import screen.EntropyScreen; import util.GameUtil; import util.Registry; +import static preference.PreferenceSettingKt.getPreference; + public class CardLabel extends JLabel - implements Registry { private String card = ""; private boolean faceUp = false; @@ -21,11 +23,11 @@ public void refreshIcon() { return; } - - String deckDirectory = prefs.get(PREFERENCES_STRING_DECK_DIRECTORY, Registry.DECK_DIRECTORY_CLASSIC); - String jokerDirectory = prefs.get(PREFERENCES_STRING_JOKER_DIRECTORY, Registry.JOKER_DIRECTORY_CLASSIC); - String numberOfColours = prefs.get(PREFERENCES_STRING_NUMBER_OF_COLOURS, Registry.TWO_COLOURS); - String back = prefs.get(PREFERENCES_STRING_CARD_BACKS, Registry.BACK_CODE_CLASSIC_BLUE); + + String deckDesign = getPreference(PreferenceSetting.DeckDesign); + String jokerDesign = getPreference(PreferenceSetting.JokerDesign); + String numberOfColours = getPreference(PreferenceSetting.NumberOfColours); + String back = getPreference(PreferenceSetting.CardBacks); if (faded) { back = "backFaded"; @@ -33,15 +35,15 @@ public void refreshIcon() if (!faceUp) { - setIcon(new ImageIcon(EntropyScreen.class.getResource("/backs/" + back + ".png"))); + setIcon(new ImageIcon(getClass().getResource("/backs/" + back + ".png"))); } else if (faded) { - setIcon(GameUtil.getFadedImageForCard(card, deckDirectory, jokerDirectory)); + setIcon(GameUtil.getFadedImageForCard(card, deckDesign, jokerDesign)); } else { - setIcon(GameUtil.getImageForCard(card, deckDirectory, jokerDirectory, numberOfColours)); + setIcon(GameUtil.getImageForCard(card, deckDesign, jokerDesign, numberOfColours)); } } diff --git a/client/src/main/java/object/ReplayTable.java b/client/src/main/java/object/ReplayTable.java index 3d9b7338..03bf23ac 100644 --- a/client/src/main/java/object/ReplayTable.java +++ b/client/src/main/java/object/ReplayTable.java @@ -25,6 +25,7 @@ import javax.swing.table.TableModel; import javax.swing.table.TableRowSorter; +import preference.PreferenceSetting; import screen.ReplayDialog; import screen.ReplayFilterPanel; import screen.ScreenCache; @@ -37,12 +38,12 @@ import util.ReplayRowWrapper; import util.TableUtil; +import static preference.PreferenceSettingKt.getPreference; import static screen.ScreenCacheKt.FILE_REPLAY; import static utils.CoreGlobals.logger; public class ReplayTable extends JTable - implements MouseListener, - Registry + implements MouseListener { private static final int INDEX_OF_DATETIME_COLUMN = 0; private static final int INDEX_OF_NAME_COLUMN = INDEX_OF_DATETIME_COLUMN + 1; @@ -167,11 +168,11 @@ private void stripOutHiddenAndRemovedColumns() removeColumn(getColumnModel().getColumn(INDEX_OF_COMPLETED_COLUMN)); removeColumn(getColumnModel().getColumn(INDEX_OF_FILENAME_COLUMN)); - boolean showGameMode = prefs.getBoolean(PREFERENCES_BOOLEAN_INCLUDE_GAME_MODE_COLUMN, true); - boolean showRounds = prefs.getBoolean(PREFERENCES_BOOLEAN_INCLUDE_ROUNDS_COLUMN, false); - boolean showPlayers = prefs.getBoolean(PREFERENCES_BOOLEAN_INCLUDE_PLAYERS_COLUMN, true); - boolean showCards = prefs.getBoolean(PREFERENCES_BOOLEAN_INCLUDE_CARDS_COLUMN, false); - boolean showRoomName = prefs.getBoolean(PREFERENCES_BOOLEAN_INCLUDE_ROOM_NAME_COLUMN, false); + boolean showGameMode = getPreference(PreferenceSetting.IncludeGameModeColumn); + boolean showRounds = getPreference(PreferenceSetting.IncludeRoundsColumn); + boolean showPlayers = getPreference(PreferenceSetting.IncludePlayersColumn); + boolean showCards = getPreference(PreferenceSetting.IncludeCardsColumn); + boolean showRoomName = getPreference(PreferenceSetting.IncludeRoomNameColumn); if (!showCards) { diff --git a/client/src/main/java/online/screen/GameRoom.java b/client/src/main/java/online/screen/GameRoom.java index c287a59a..53fb20ee 100644 --- a/client/src/main/java/online/screen/GameRoom.java +++ b/client/src/main/java/online/screen/GameRoom.java @@ -1,11 +1,13 @@ package online.screen; import achievement.Reward; +import bean.BidListCellRenderer; import game.*; import http.dto.RoomSummary; import object.*; import online.util.XmlBuilderClient; import org.w3c.dom.Document; +import preference.PreferenceSetting; import screen.*; import util.*; @@ -25,6 +27,7 @@ import java.util.prefs.Preferences; import static game.RegistryUtilKt.writeActions; +import static preference.PreferenceSettingKt.getPreference; import static utils.ColourUtilKt.getColourForPlayerNumber; import static utils.CoreGlobals.logger; @@ -703,7 +706,7 @@ public void startGame(int personToStart) } adjustPlayersBasedOnHands(); - playBlind = prefs.getBoolean(PREFERENCES_BOOLEAN_PLAY_BLIND, false); + playBlind = getPreference(PreferenceSetting.PlayBlind); hasActedBlindThisGame = false; handPanel.setHasViewedHandThisGame(false); handPanel.setViewCardsVisibility(playBlind && playerIsEnabled(playerNumberLocal)); @@ -1348,7 +1351,7 @@ public boolean bidHistoryContainsBid() @Override public void requestFocus() { - boolean popUpRoom = prefs.getBoolean(PREFERENCES_BOOLEAN_POP_UP_ROOMS, true); + boolean popUpRoom = getPreference(PreferenceSetting.PopUpRooms); if (popUpRoom) { diff --git a/client/src/main/java/online/util/ResponseHandler.java b/client/src/main/java/online/util/ResponseHandler.java index bc95c904..a24853a2 100644 --- a/client/src/main/java/online/util/ResponseHandler.java +++ b/client/src/main/java/online/util/ResponseHandler.java @@ -10,6 +10,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import preference.PreferenceSetting; import screen.ScreenCache; import util.*; import utils.CoreGlobals; @@ -18,6 +19,7 @@ import java.util.HashMap; import java.util.List; +import static preference.PreferenceSettingKt.getPreference; import static utils.CoreGlobals.logger; public class ResponseHandler implements XmlConstants @@ -233,7 +235,7 @@ private static void handleNewRoundResponse(Element root, EntropyLobby lobby) */ private static void pauseDuringChallenge() { - int sleepMillis = 1000 * Registry.prefs.getInt(Registry.PREFERENCES_INT_AUTO_START_SECONDS, 2); + int sleepMillis = 1000 * getPreference(PreferenceSetting.AutoStartSeconds); try { Thread.sleep(sleepMillis); } catch (Throwable t) {} } diff --git a/client/src/main/java/screen/AbstractPreferencesPanel.java b/client/src/main/java/screen/AbstractPreferencesPanel.java index 4b3dd0a0..268f680a 100644 --- a/client/src/main/java/screen/AbstractPreferencesPanel.java +++ b/client/src/main/java/screen/AbstractPreferencesPanel.java @@ -8,8 +8,7 @@ import java.awt.event.ActionListener; public abstract class AbstractPreferencesPanel extends JPanel - implements Registry, - ActionListener + implements ActionListener { protected PreferencesDialog parent = null; diff --git a/client/src/main/java/screen/ClearDataDialog.java b/client/src/main/java/screen/ClearDataDialog.java index 44b4c32c..27df28a2 100644 --- a/client/src/main/java/screen/ClearDataDialog.java +++ b/client/src/main/java/screen/ClearDataDialog.java @@ -9,8 +9,7 @@ import java.awt.event.ActionListener; import java.awt.event.WindowEvent; -import static util.ClientGlobals.achievementStore; -import static util.ClientGlobals.rewardStore; +import static util.ClientGlobals.*; public class ClearDataDialog extends JDialog implements ActionListener, @@ -174,18 +173,7 @@ private void removeStatisticsVariablesFromNode() private void resetPreferences() { - prefs.remove(PREFERENCES_BOOLEAN_PLAY_BLIND); - prefs.remove(PREFERENCES_BOOLEAN_PLAY_WITH_HANDICAP); - prefs.remove(PREFERENCES_XML_API_SETTINGS); - prefs.remove(PREFERENCES_STRING_GAME_MODE); - prefs.remove(PREFERENCES_INT_HANDICAP_AMOUNT); - prefs.remove(SHARED_INT_JOKER_QUANTITY); - prefs.remove(SHARED_INT_JOKER_VALUE); - prefs.remove(PREFERENCES_STRING_CARD_BACKS); - prefs.remove(PREFERENCES_STRING_LOOK_AND_FEEL); - prefs.remove(PREFERENCES_STRING_DECK_DIRECTORY); - prefs.remove(PREFERENCES_STRING_JOKER_DIRECTORY); - prefs.remove(PREFERENCES_STRING_NUMBER_OF_COLOURS); + preferenceStore.clear(); } private void closeDialog() diff --git a/client/src/main/java/screen/ConfigureColumnsDialog.java b/client/src/main/java/screen/ConfigureColumnsDialog.java index f9fe80ed..1f9b20ce 100644 --- a/client/src/main/java/screen/ConfigureColumnsDialog.java +++ b/client/src/main/java/screen/ConfigureColumnsDialog.java @@ -8,11 +8,14 @@ import javax.swing.JDialog; import javax.swing.JPanel; +import preference.PreferenceSetting; import util.Debug; import util.Registry; +import static preference.PreferenceSettingKt.getPreference; +import static util.ClientGlobals.preferenceStore; + public class ConfigureColumnsDialog extends JDialog - implements Registry { private boolean showGameMode = false; private boolean showRounds = false; @@ -56,11 +59,11 @@ public ConfigureColumnsDialog() private void initVariables() { - showGameMode = prefs.getBoolean(PREFERENCES_BOOLEAN_INCLUDE_GAME_MODE_COLUMN, true); - showRounds = prefs.getBoolean(PREFERENCES_BOOLEAN_INCLUDE_ROUNDS_COLUMN, false); - showPlayers = prefs.getBoolean(PREFERENCES_BOOLEAN_INCLUDE_PLAYERS_COLUMN, true); - showCards = prefs.getBoolean(PREFERENCES_BOOLEAN_INCLUDE_CARDS_COLUMN, false); - showRoomName = prefs.getBoolean(PREFERENCES_BOOLEAN_INCLUDE_ROOM_NAME_COLUMN, false); + showGameMode = getPreference(PreferenceSetting.IncludeGameModeColumn); + showRounds = getPreference(PreferenceSetting.IncludeRoundsColumn); + showPlayers = getPreference(PreferenceSetting.IncludePlayersColumn); + showCards = getPreference(PreferenceSetting.IncludeCardsColumn); + showRoomName = getPreference(PreferenceSetting.IncludeRoomNameColumn); chckbxGameMode.setSelected(showGameMode); chckbxRounds.setSelected(showRounds); @@ -71,11 +74,11 @@ private void initVariables() private void saveSettings() { - prefs.putBoolean(PREFERENCES_BOOLEAN_INCLUDE_GAME_MODE_COLUMN, chckbxGameMode.isSelected()); - prefs.putBoolean(PREFERENCES_BOOLEAN_INCLUDE_ROOM_NAME_COLUMN, chckbxRoomName.isSelected()); - prefs.putBoolean(PREFERENCES_BOOLEAN_INCLUDE_ROUNDS_COLUMN, chckbxRounds.isSelected()); - prefs.putBoolean(PREFERENCES_BOOLEAN_INCLUDE_PLAYERS_COLUMN, chckbxPlayers.isSelected()); - prefs.putBoolean(PREFERENCES_BOOLEAN_INCLUDE_CARDS_COLUMN, chckbxCards.isSelected()); + preferenceStore.save(PreferenceSetting.IncludeGameModeColumn, chckbxGameMode.isSelected()); + preferenceStore.save(PreferenceSetting.IncludeRoomNameColumn, chckbxRoomName.isSelected()); + preferenceStore.save(PreferenceSetting.IncludeRoundsColumn, chckbxRounds.isSelected()); + preferenceStore.save(PreferenceSetting.IncludePlayersColumn, chckbxPlayers.isSelected()); + preferenceStore.save(PreferenceSetting.IncludeCardsColumn, chckbxCards.isSelected()); dispose(); } diff --git a/client/src/main/java/screen/EntropyBidPanel.java b/client/src/main/java/screen/EntropyBidPanel.java index 64640cb9..9add7466 100644 --- a/client/src/main/java/screen/EntropyBidPanel.java +++ b/client/src/main/java/screen/EntropyBidPanel.java @@ -26,10 +26,15 @@ import achievement.Reward; import game.EntropyBidAction; +import game.RenderingUtilKt; import game.Suit; +import preference.PreferenceSetting; import util.Debug; import util.Registry; +import static preference.PreferenceSettingKt.FOUR_COLOURS; +import static preference.PreferenceSettingKt.getPreference; + public class EntropyBidPanel extends BidPanel implements ActionListener, ChangeListener, @@ -182,7 +187,7 @@ public void init(int maxBid, int totalNumberOfCards, boolean online, boolean inc setBidButtonColours(); totalCardsLabel.setText("x " + totalNumberOfCards); - String back = prefs.get(PREFERENCES_STRING_CARD_BACKS, Registry.BACK_CODE_CLASSIC_BLUE); + String back = getPreference(PreferenceSetting.CardBacks); smallCardIcon.setIcon(new ImageIcon(EntropyScreen.class.getResource("/backs/" + back + "Small.png"))); } @@ -266,7 +271,7 @@ private void updateSelectionForLastBidSuit() { @Override public void fireAppearancePreferencesChange() { - String back = prefs.get(PREFERENCES_STRING_CARD_BACKS, Registry.BACK_CODE_CLASSIC_BLUE); + String back = getPreference(PreferenceSetting.CardBacks); smallCardIcon.setIcon(new ImageIcon(EntropyScreen.class.getResource("/backs/" + back + "Small.png"))); updateBidAmountDisplay(); @@ -277,13 +282,13 @@ private void updateBidAmountDisplay() { String spaceStr = bidSuit == Suit.Moons ? "":" "; bidAmountDisplay.setText(bidSlider.getValue() + spaceStr + bidSuit.getUnicodeStr()); - bidAmountDisplay.setForeground(bidSuit.getColour()); + bidAmountDisplay.setForeground(RenderingUtilKt.getColour(bidSuit)); } private void setBidButtonColours() { - String numberOfColoursStr = prefs.get(PREFERENCES_STRING_NUMBER_OF_COLOURS, Registry.TWO_COLOURS); - boolean fourColours = (numberOfColoursStr.equals(Registry.FOUR_COLOURS)); + String numberOfColoursStr = getPreference(PreferenceSetting.NumberOfColours); + boolean fourColours = (numberOfColoursStr.equals(FOUR_COLOURS)); if (fourColours) { @@ -345,7 +350,7 @@ public void loadState(Preferences savedGame) String label = savedGame.get(SAVED_GAME_STRING_TOTAL_CARDS_LABEL, "0"); totalCardsLabel.setText(label); - String back = prefs.get(PREFERENCES_STRING_CARD_BACKS, Registry.BACK_CODE_CLASSIC_BLUE); + String back = getPreference(PreferenceSetting.CardBacks); smallCardIcon.setIcon(new ImageIcon(EntropyScreen.class.getResource("/backs/" + back + "Small.png"))); } diff --git a/client/src/main/java/screen/EntropyScreen.java b/client/src/main/java/screen/EntropyScreen.java index 58cab24b..eb9c7e92 100644 --- a/client/src/main/java/screen/EntropyScreen.java +++ b/client/src/main/java/screen/EntropyScreen.java @@ -6,12 +6,14 @@ import game.GameMode; import game.Suit; import object.EntropyAchievementsTracker; +import preference.PreferenceSetting; import util.Registry; import static game.CardsUtilKt.countSuit; import static game.CheatUtilKt.getMaxBidString; import static game.EntropyUtilKt.perfectBidAmount; import static game.EntropyUtilKt.perfectBidSuit; +import static preference.PreferenceSettingKt.getPreference; public class EntropyScreen extends GameScreen { @@ -22,7 +24,7 @@ public class EntropyScreen extends GameScreen public EntropyScreen() { setFocusable(true); - bidPanel = new EntropyBidPanel(prefs.get(PREFERENCES_STRING_PLAYER_NAME, "Player"), handPanel); + bidPanel = new EntropyBidPanel(getPreference(PreferenceSetting.PlayerName), handPanel); bidPanel.showBidPanel(false); setLayout(new BorderLayout(0, 0)); diff --git a/client/src/main/java/screen/GameScreen.java b/client/src/main/java/screen/GameScreen.java index e8be0f7b..9861a22a 100644 --- a/client/src/main/java/screen/GameScreen.java +++ b/client/src/main/java/screen/GameScreen.java @@ -1,9 +1,10 @@ package screen; import achievement.AchievementSetting; +import bean.BidListCellRenderer; import game.*; -import object.BidListCellRenderer; import object.Player; +import preference.PreferenceSetting; import util.*; import javax.swing.*; @@ -16,8 +17,10 @@ import static game.CheatUtilKt.containsNonJoker; import static game.RegistryUtilKt.populateActions; import static game.RegistryUtilKt.writeActions; +import static preference.PreferenceSettingKt.getPreference; import static screen.ScreenCacheKt.IN_GAME_REPLAY; import static util.ClientGlobals.achievementStore; +import static util.ClientGlobals.preferenceStore; import static utils.CoreGlobals.logger; public abstract class GameScreen> extends TransparentPanel @@ -305,14 +308,14 @@ else if (opponentOne.isEnabled()) private void getNewGameVariablesFromRegistry() { - playBlind = prefs.getBoolean(PREFERENCES_BOOLEAN_PLAY_BLIND, false); - playWithHandicap = prefs.getBoolean(PREFERENCES_BOOLEAN_PLAY_WITH_HANDICAP, false); - handicapAmount = prefs.getInt(PREFERENCES_INT_HANDICAP_AMOUNT, 1); - opponentTwo.setEnabled(prefs.getBoolean(PREFERENCES_BOOLEAN_OPPONENT_TWO_ENABLED, true)); - opponentThree.setEnabled(prefs.getBoolean(PREFERENCES_BOOLEAN_OPPONENT_THREE_ENABLED, true)); - opponentOne.setStrategy(prefs.get(PREFERENCES_STRING_OPPONENT_ONE_STRATEGY, "Basic")); - opponentTwo.setStrategy(prefs.get(PREFERENCES_STRING_OPPONENT_TWO_STRATEGY, "Basic")); - opponentThree.setStrategy(prefs.get(PREFERENCES_STRING_OPPONENT_THREE_STRATEGY, "Basic")); + playBlind = getPreference(PreferenceSetting.PlayBlind); + playWithHandicap = getPreference(PreferenceSetting.PlayWithHandicap); + handicapAmount = getPreference(PreferenceSetting.HandicapAmount); + opponentTwo.setEnabled(getPreference(PreferenceSetting.OpponentTwoEnabled)); + opponentThree.setEnabled(getPreference(PreferenceSetting.OpponentThreeEnabled)); + opponentOne.setStrategy(getPreference(PreferenceSetting.OpponentOneStrategy)); + opponentTwo.setStrategy(getPreference(PreferenceSetting.OpponentTwoStrategy)); + opponentThree.setStrategy(getPreference(PreferenceSetting.OpponentThreeStrategy)); settings = GameSettings.fromRegistry(prefs, getGameMode()); @@ -430,12 +433,12 @@ protected void roundEnded(int playerLastToAct) else { currentlyOnChallenge = true; - boolean autoStart = prefs.getBoolean(PREFERENCES_BOOLEAN_AUTO_START_NEXT_ROUND, false); + boolean autoStart = getPreference(PreferenceSetting.AutoStartNextRound); if (autoStart) { - int seconds = prefs.getInt(PREFERENCES_INT_AUTO_START_SECONDS, 2); - nextRoundTimer.schedule(new NewRoundTask(), seconds * 1000); + int seconds = getPreference(PreferenceSetting.AutoStartSeconds); + nextRoundTimer.schedule(new NewRoundTask(), seconds * 1000L); } else { @@ -887,9 +890,7 @@ public void processCpuTurn(int opponentNumber) handPanel.selectPlayerInAwtThread(opponentNumber, true); bidPanel.enableBidPanel(false); - int gameSpeed = prefs.getInt(PREFERENCES_INT_GAME_SPEED, 1000); - - cpuTurn.schedule(new DelayedOpponentTurn(currentPlayer), gameSpeed); + cpuTurn.schedule(new DelayedOpponentTurn(currentPlayer), getPreference(PreferenceSetting.GameSpeed)); } private Collection allPlayers() { diff --git a/client/src/main/java/screen/HandPanelMk2.java b/client/src/main/java/screen/HandPanelMk2.java index 42f17bb2..8dec0a81 100644 --- a/client/src/main/java/screen/HandPanelMk2.java +++ b/client/src/main/java/screen/HandPanelMk2.java @@ -4,6 +4,7 @@ import object.CardLabel; import object.PlayerLabel; import online.screen.EntropyLobby; +import preference.PreferenceSetting; import util.*; import javax.swing.*; @@ -21,6 +22,7 @@ import java.util.prefs.Preferences; import static game.CardsUtilKt.isCardRelevant; +import static preference.PreferenceSettingKt.getPreference; public class HandPanelMk2 extends TransparentPanel implements ActionListener, @@ -738,10 +740,10 @@ public void fireAppearancePreferencesChange() public void initPlayerNames() { - playerName = prefs.get(PREFERENCES_STRING_PLAYER_NAME, "Player"); - opponentOneName = prefs.get(PREFERENCES_STRING_OPPONENT_ONE_NAME, "Mark"); - opponentTwoName = prefs.get(PREFERENCES_STRING_OPPONENT_TWO_NAME, "Dave"); - opponentThreeName = prefs.get(PREFERENCES_STRING_OPPONENT_THREE_NAME, "Tom"); + playerName = getPreference(PreferenceSetting.PlayerName); + opponentOneName = getPreference(PreferenceSetting.OpponentOneName); + opponentTwoName = getPreference(PreferenceSetting.OpponentTwoName); + opponentThreeName = getPreference(PreferenceSetting.OpponentThreeName); } public void loadPlayerNames(Preferences savedGame) diff --git a/client/src/main/java/screen/MainScreen.java b/client/src/main/java/screen/MainScreen.java index 8d0098cd..2818b652 100644 --- a/client/src/main/java/screen/MainScreen.java +++ b/client/src/main/java/screen/MainScreen.java @@ -4,14 +4,15 @@ import achievement.AchievementUtilKt; import achievement.Reward; import bean.AbstractDevScreen; +import bean.BidListCellRenderer; import game.GameMode; import game.PlayerAction; -import object.BidListCellRenderer; import object.Player; import online.screen.EntropyLobby; import online.screen.TestHarness; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import preference.PreferenceSetting; import screen.achievement.AchievementsDialog; import screen.preference.PreferencesDialog; import settings.Setting; @@ -34,6 +35,7 @@ import static achievement.AchievementUtilKt.getAchievementsEarned; import static achievement.AchievementUtilKt.unlockRewards; +import static preference.PreferenceSettingKt.getPreference; import static screen.ScreenCacheKt.IN_GAME_REPLAY; import static screen.online.PlayOnlineDialogKt.showPlayOnlineDialog; import static util.ClientGlobals.achievementStore; @@ -262,7 +264,7 @@ public void startNewGame() { if (overwriteSavedGame() && quitCurrentGame()) { - gameMode = GameMode.valueOf(prefs.get(Registry.PREFERENCES_STRING_GAME_MODE, GameMode.Entropy.name())); + gameMode = GameMode.valueOf(getPreference(PreferenceSetting.GameMode)); selectGameScreen(gameMode); lblBidHistory.setVisible(true); btnReplay.setVisible(true); @@ -474,7 +476,7 @@ private void doStuffOnExit() private void saveGame() throws Throwable { - boolean autosave = prefs.getBoolean(Registry.PREFERENCES_BOOLEAN_AUTOSAVE, false); + boolean autosave = getPreference(PreferenceSetting.AutoSave); if (autosave) { @@ -937,8 +939,8 @@ else if (source == mntmAchievements) } else if (source == mntmViewReplays) { - int width = prefs.getInt(Registry.PREFERENCES_INT_REPLAY_VIEWER_WIDTH, 875); - int height = prefs.getInt(Registry.PREFERENCES_INT_REPLAY_VIEWER_HEIGHT, 475); + int width = getPreference(PreferenceSetting.ReplayViewerWidth); + int height = getPreference(PreferenceSetting.ReplayViewerHeight); ReplayInterface replayInterface = ScreenCache.get(ReplayInterface.class); replayInterface.setTitle("Replay Viewer"); diff --git a/client/src/main/java/screen/PreferencesPanelAppearance.java b/client/src/main/java/screen/PreferencesPanelAppearance.java index f3e1aed0..e1e0e6cd 100644 --- a/client/src/main/java/screen/PreferencesPanelAppearance.java +++ b/client/src/main/java/screen/PreferencesPanelAppearance.java @@ -29,16 +29,20 @@ import achievement.Reward; import bean.ComboBoxItem; import object.DisabledComboBoxModel; +import preference.PreferenceSetting; import util.GameUtil; +import static preference.PreferenceSettingKt.*; +import static util.ClientGlobals.preferenceStore; + public class PreferencesPanelAppearance extends AbstractPreferencesPanel implements ItemListener { - private String deckDirectory = DECK_DIRECTORY_CLASSIC; - private String jokerDirectory = JOKER_DIRECTORY_CLASSIC; - private String cardBacks = BACK_CODE_CLASSIC_BLUE; - private String numberOfColours = FOUR_COLOURS; - private String lookAndFeel = DEFAULT_LOOK_AND_FEEL; + private String deckDesign = ""; + private String jokerDesign = ""; + private String cardBacks = ""; + private String numberOfColours = ""; + private String lookAndFeel = ""; public PreferencesPanelAppearance() { @@ -206,22 +210,22 @@ public boolean valid() @Override public void savePreferences() { - prefs.put(PREFERENCES_STRING_DECK_DIRECTORY, deckDirectory); - prefs.put(PREFERENCES_STRING_JOKER_DIRECTORY, jokerDirectory); - prefs.put(PREFERENCES_STRING_NUMBER_OF_COLOURS, numberOfColours); - prefs.put(PREFERENCES_STRING_CARD_BACKS, cardBacks); - prefs.put(PREFERENCES_STRING_LOOK_AND_FEEL, (String)comboBoxLookAndFeel.getSelectedItem()); + preferenceStore.save(PreferenceSetting.DeckDesign, deckDesign); + preferenceStore.save(PreferenceSetting.JokerDesign, jokerDesign); + preferenceStore.save(PreferenceSetting.NumberOfColours, numberOfColours); + preferenceStore.save(PreferenceSetting.CardBacks, cardBacks); + preferenceStore.save(PreferenceSetting.LookAndFeel, (String)comboBoxLookAndFeel.getSelectedItem()); ScreenCache.get(MainScreen.class).fireAppearancePreferencesChange(); } private void getVariablesFromPrefs() { - deckDirectory = prefs.get(PREFERENCES_STRING_DECK_DIRECTORY, DECK_DIRECTORY_CLASSIC); - jokerDirectory = prefs.get(PREFERENCES_STRING_JOKER_DIRECTORY, JOKER_DIRECTORY_CLASSIC); - numberOfColours = prefs.get(PREFERENCES_STRING_NUMBER_OF_COLOURS, TWO_COLOURS); - cardBacks = prefs.get(PREFERENCES_STRING_CARD_BACKS, BACK_CODE_CLASSIC_BLUE); - lookAndFeel = prefs.get(PREFERENCES_STRING_LOOK_AND_FEEL, DEFAULT_LOOK_AND_FEEL); + deckDesign = getPreference(PreferenceSetting.DeckDesign); + jokerDesign = getPreference(PreferenceSetting.JokerDesign); + numberOfColours = getPreference(PreferenceSetting.NumberOfColours); + cardBacks = getPreference(PreferenceSetting.CardBacks); + lookAndFeel = getPreference(PreferenceSetting.LookAndFeel); } private void hideLockedFields() @@ -233,10 +237,10 @@ private void hideLockedFields() private void refreshDeckPreview() { - ImageIcon jackClubs = GameUtil.getImageForCard("Jc", deckDirectory, jokerDirectory, numberOfColours); - ImageIcon queenDiamonds = GameUtil.getImageForCard("Qd", deckDirectory, jokerDirectory, numberOfColours); - ImageIcon kingHearts = GameUtil.getImageForCard("Kh", deckDirectory, jokerDirectory, numberOfColours); - ImageIcon aceSpades = GameUtil.getImageForCard("As", deckDirectory, jokerDirectory, numberOfColours); + ImageIcon jackClubs = GameUtil.getImageForCard("Jc", deckDesign, jokerDesign, numberOfColours); + ImageIcon queenDiamonds = GameUtil.getImageForCard("Qd", deckDesign, jokerDesign, numberOfColours); + ImageIcon kingHearts = GameUtil.getImageForCard("Kh", deckDesign, jokerDesign, numberOfColours); + ImageIcon aceSpades = GameUtil.getImageForCard("As", deckDesign, jokerDesign, numberOfColours); labelJc.setIcon(jackClubs); labelQd.setIcon(queenDiamonds); labelKh.setIcon(kingHearts); @@ -245,10 +249,10 @@ private void refreshDeckPreview() private void refreshJokerPreview() { - ImageIcon jo0 = GameUtil.getImageForCard("Jo0", deckDirectory, jokerDirectory, numberOfColours); - ImageIcon jo1 = GameUtil.getImageForCard("Jo1", deckDirectory, jokerDirectory, numberOfColours); - ImageIcon jo2 = GameUtil.getImageForCard("Jo2", deckDirectory, jokerDirectory, numberOfColours); - ImageIcon jo3 = GameUtil.getImageForCard("Jo3", deckDirectory, jokerDirectory, numberOfColours); + ImageIcon jo0 = GameUtil.getImageForCard("Jo0", deckDesign, jokerDesign, numberOfColours); + ImageIcon jo1 = GameUtil.getImageForCard("Jo1", deckDesign, jokerDesign, numberOfColours); + ImageIcon jo2 = GameUtil.getImageForCard("Jo2", deckDesign, jokerDesign, numberOfColours); + ImageIcon jo3 = GameUtil.getImageForCard("Jo3", deckDesign, jokerDesign, numberOfColours); labelJo0.setIcon(jo0); labelJo1.setIcon(jo1); labelJo2.setIcon(jo2); @@ -265,7 +269,7 @@ private void selectCardBackBasedOnPreference() ComboBoxItem selectedItem = getSelectedItemForCode(backs, cardBacks); if (selectedItem == null) { - selectedItem = new ComboBoxItem<>(BACK_CODE_CLASSIC_BLUE, "Blue"); + selectedItem = new ComboBoxItem<>("backBlue", "Blue"); } comboBoxBacks.setSelectedItem(selectedItem); @@ -275,7 +279,7 @@ private Vector> initialiseBacksVector() { Vector> backs = new Vector<>(); - backs.addElement(new ComboBoxItem<>(BACK_CODE_CLASSIC_BLUE, "Blue")); + backs.addElement(new ComboBoxItem<>("backBlue", "Blue")); backs.addElement(new ComboBoxItem<>("backRed", "Red")); addIfUnlocked(backs, new ComboBoxItem<>("backGreen", "Green"), Reward.FourColours); @@ -343,7 +347,7 @@ private void refreshCardBackPreview() ComboBoxItem selection = (ComboBoxItem)comboBoxBacks.getSelectedItem(); if (selection == null) { - cardBacks = BACK_CODE_CLASSIC_BLUE; + cardBacks = comboBoxBacks.getItemAt(0).getHiddenData(); } else { @@ -358,20 +362,20 @@ private void selectRadioButtonsBasedOnDirectories() { cbFourColour.setSelected(numberOfColours.equals(FOUR_COLOURS)); - if (deckDirectory.equals(DECK_DIRECTORY_CLASSIC)) + if (deckDesign.equals(DECK_DESIGN_CLASSIC)) { rdbtnClassicDesign.setSelected(true); } - else if (deckDirectory.equals(DECK_DIRECTORY_ALTERNATE)) + else if (deckDesign.equals(DECK_DESIGN_ALTERNATE)) { rdbtnMinimalistDesign.setSelected(true); } - if (jokerDirectory.equals(JOKER_DIRECTORY_CLASSIC)) + if (jokerDesign.equals(JOKER_DESIGN_CLASSIC)) { rdbtnClassicJokers.setSelected(true); } - else if (jokerDirectory.equals(JOKER_DIRECTORY_DEVELOPERS)) + else if (jokerDesign.equals(JOKER_DESIGN_DEVELOPERS)) { rdbtnDeveloperJokers.setSelected(true); } @@ -383,22 +387,22 @@ public void actionPerformed(ActionEvent arg0) Object source = arg0.getSource(); if (source == rdbtnClassicDesign) { - deckDirectory = DECK_DIRECTORY_CLASSIC; + deckDesign = DECK_DESIGN_CLASSIC; refreshDeckPreview(); } else if (source == rdbtnMinimalistDesign) { - deckDirectory = DECK_DIRECTORY_ALTERNATE; + deckDesign = DECK_DESIGN_ALTERNATE; refreshDeckPreview(); } else if (source == rdbtnClassicJokers) { - jokerDirectory = JOKER_DIRECTORY_CLASSIC; + jokerDesign = JOKER_DESIGN_CLASSIC; refreshJokerPreview(); } else if (source == rdbtnDeveloperJokers) { - jokerDirectory = JOKER_DIRECTORY_DEVELOPERS; + jokerDesign = JOKER_DESIGN_DEVELOPERS; refreshJokerPreview(); } else if (source == comboBoxBacks) diff --git a/client/src/main/java/screen/PreferencesPanelGameplay.java b/client/src/main/java/screen/PreferencesPanelGameplay.java index cc4c474b..e837bc5f 100644 --- a/client/src/main/java/screen/PreferencesPanelGameplay.java +++ b/client/src/main/java/screen/PreferencesPanelGameplay.java @@ -23,11 +23,17 @@ import achievement.Reward; import game.GameMode; +import preference.PreferenceSetting; import util.Debug; +import util.Registry; + +import static preference.PreferenceSettingKt.getPreference; +import static util.ClientGlobals.preferenceStore; public class PreferencesPanelGameplay extends AbstractPreferencesPanel implements ChangeListener, - ItemListener + ItemListener, + Registry { private GameMode gameMode = GameMode.Entropy; private boolean includeJokers = false; @@ -205,13 +211,14 @@ public void savePreferences() prefs.putBoolean(SHARED_BOOLEAN_NEGATIVE_JACKS, negativeJacks); prefs.putInt(SHARED_INT_JOKER_QUANTITY, jokerQuantity); prefs.putInt(SHARED_INT_JOKER_VALUE, jokerValue); - prefs.putBoolean(PREFERENCES_BOOLEAN_PLAY_WITH_HANDICAP, playWithHandicap); - prefs.putInt(PREFERENCES_INT_HANDICAP_AMOUNT, handicapAmount); - prefs.putBoolean(PREFERENCES_BOOLEAN_PLAY_BLIND, playBlind); + + preferenceStore.save(PreferenceSetting.PlayWithHandicap, playWithHandicap); + preferenceStore.save(PreferenceSetting.HandicapAmount, handicapAmount); + preferenceStore.save(PreferenceSetting.PlayBlind, playBlind); prefs.putBoolean(SHARED_BOOLEAN_INCLUDE_STARS, includeStars); prefs.putBoolean(SHARED_BOOLEAN_INCLUDE_MOONS, includeMoons); prefs.putBoolean(SHARED_BOOLEAN_CARD_REVEAL, cardReveal); - prefs.put(PREFERENCES_STRING_GAME_MODE, gameMode.name()); + preferenceStore.save(PreferenceSetting.GameMode, gameMode.name()); } private void getVariablesFromPreferences() @@ -220,14 +227,14 @@ private void getVariablesFromPreferences() jokerQuantity = prefs.getInt(SHARED_INT_JOKER_QUANTITY, 2); includeJokers = jokerQuantity > 0; jokerValue = prefs.getInt(SHARED_INT_JOKER_VALUE, 2); - playWithHandicap = prefs.getBoolean(PREFERENCES_BOOLEAN_PLAY_WITH_HANDICAP, false); - handicapAmount = Math.max(prefs.getInt(PREFERENCES_INT_HANDICAP_AMOUNT, 1), 1); - playBlind = prefs.getBoolean(PREFERENCES_BOOLEAN_PLAY_BLIND, false); + playWithHandicap = getPreference(PreferenceSetting.PlayWithHandicap); + handicapAmount = getPreference(PreferenceSetting.HandicapAmount); + playBlind = getPreference(PreferenceSetting.PlayBlind); includeStars = prefs.getBoolean(SHARED_BOOLEAN_INCLUDE_STARS, false); includeMoons = prefs.getBoolean(SHARED_BOOLEAN_INCLUDE_MOONS, false); negativeJacks = prefs.getBoolean(SHARED_BOOLEAN_NEGATIVE_JACKS, false); cardReveal = prefs.getBoolean(SHARED_BOOLEAN_CARD_REVEAL, false); - gameMode = GameMode.valueOf(prefs.get(PREFERENCES_STRING_GAME_MODE, GameMode.Entropy.name())); + gameMode = GameMode.valueOf(getPreference(PreferenceSetting.GameMode)); } private void adjustHandicapSpinner() diff --git a/client/src/main/java/screen/PreferencesPanelMisc.java b/client/src/main/java/screen/PreferencesPanelMisc.java index dea054de..5337a036 100644 --- a/client/src/main/java/screen/PreferencesPanelMisc.java +++ b/client/src/main/java/screen/PreferencesPanelMisc.java @@ -19,23 +19,20 @@ import javax.swing.SpinnerNumberModel; import javax.swing.SwingConstants; -import util.Debug; -import util.DialogUtil; -import util.Registry; -import util.ReplayFileUtil; +import preference.PreferenceSetting; +import util.*; + +import static preference.PreferenceSettingKt.*; +import static util.ClientGlobals.preferenceStore; public class PreferencesPanelMisc extends AbstractPreferencesPanel implements ItemListener { - private static final int GAME_SPEED_SLOW = 1500; - private static final int GAME_SPEED_MEDIUM = 1000; - private static final int GAME_SPEED_FAST = 500; - private boolean autosave = false; private int gameSpeed = GAME_SPEED_MEDIUM; private boolean saveReplays = false; private String replayDirectory = ""; - private int replayDefault = OPEN_ON_FIRST_ROUND; + private boolean openReplayOnFirstRound = false; private boolean autoStartNextRound = false; private int autoStartSeconds = 2; //2 seconds private boolean popUpRoomsOnline = true; @@ -159,8 +156,8 @@ public void initVariables() spinnerAutoStartSeconds.setEnabled(autoStartNextRound); lblSeconds.setEnabled(autoStartNextRound); spinnerAutoStartSeconds.setValue(autoStartSeconds); - rdbtnFirstRound.setSelected(replayDefault == Registry.OPEN_ON_FIRST_ROUND); - rdbtnLastRound.setSelected(replayDefault == Registry.OPEN_ON_LAST_ROUND); + rdbtnFirstRound.setSelected(openReplayOnFirstRound); + rdbtnLastRound.setSelected(!openReplayOnFirstRound); } @Override @@ -173,38 +170,38 @@ public boolean valid() public void savePreferences() { autosave = chckbxAutosave.isSelected(); - replayDefault = rdbtnFirstRound.isSelected() ? Registry.OPEN_ON_FIRST_ROUND:Registry.OPEN_ON_LAST_ROUND; + openReplayOnFirstRound = rdbtnFirstRound.isSelected(); autoStartSeconds = (int)spinnerAutoStartSeconds.getValue(); popUpRoomsOnline = chckbxPopUpRooms.isSelected(); checkForUpdates = chckbxCheckForUpdates.isSelected(); - prefs.putBoolean(PREFERENCES_BOOLEAN_SAVE_REPLAYS, saveReplays); - prefs.putBoolean(PREFERENCES_BOOLEAN_AUTOSAVE, autosave); - prefs.put(PREFERENCES_STRING_REPLAY_DIRECTORY, replayDirectory); - prefs.putInt(PREFERENCES_INT_REPLAY_DEFAULT, replayDefault); - prefs.putBoolean(PREFERENCES_BOOLEAN_AUTO_START_NEXT_ROUND, autoStartNextRound); - prefs.putInt(PREFERENCES_INT_AUTO_START_SECONDS, autoStartSeconds); - prefs.putBoolean(PREFERENCES_BOOLEAN_POP_UP_ROOMS, popUpRoomsOnline); - prefs.putBoolean(PREFERENCES_BOOLEAN_CHECK_FOR_UPDATES, checkForUpdates); - prefs.putInt(PREFERENCES_INT_GAME_SPEED, gameSpeed); + preferenceStore.save(PreferenceSetting.SaveReplays, saveReplays); + preferenceStore.save(PreferenceSetting.AutoSave, autosave); + preferenceStore.save(PreferenceSetting.ReplayDirectory, replayDirectory); + preferenceStore.save(PreferenceSetting.OpenReplayOnFirstRound, openReplayOnFirstRound); + preferenceStore.save(PreferenceSetting.AutoStartNextRound, autoStartNextRound); + preferenceStore.save(PreferenceSetting.AutoStartSeconds, autoStartSeconds); + preferenceStore.save(PreferenceSetting.PopUpRooms, popUpRoomsOnline); + preferenceStore.save(PreferenceSetting.CheckForUpdates, checkForUpdates); + preferenceStore.save(PreferenceSetting.GameSpeed, gameSpeed); } private void getVariablesFromPrefs() { - autosave = prefs.getBoolean(PREFERENCES_BOOLEAN_AUTOSAVE, false); - gameSpeed = prefs.getInt(PREFERENCES_INT_GAME_SPEED, GAME_SPEED_MEDIUM); - saveReplays = prefs.getBoolean(PREFERENCES_BOOLEAN_SAVE_REPLAYS, false); - replayDirectory = prefs.get(PREFERENCES_STRING_REPLAY_DIRECTORY, System.getProperty("user.dir")); - replayDefault = prefs.getInt(PREFERENCES_INT_REPLAY_DEFAULT, Registry.OPEN_ON_LAST_ROUND); - autoStartNextRound = prefs.getBoolean(PREFERENCES_BOOLEAN_AUTO_START_NEXT_ROUND, false); - autoStartSeconds = prefs.getInt(PREFERENCES_INT_AUTO_START_SECONDS, 2); - popUpRoomsOnline = prefs.getBoolean(PREFERENCES_BOOLEAN_POP_UP_ROOMS, true); - checkForUpdates = prefs.getBoolean(PREFERENCES_BOOLEAN_CHECK_FOR_UPDATES, true); + autosave = getPreference(PreferenceSetting.AutoSave); + gameSpeed = getPreference(PreferenceSetting.GameSpeed); + saveReplays = getPreference(PreferenceSetting.SaveReplays); + replayDirectory = getPreference(PreferenceSetting.ReplayDirectory); + openReplayOnFirstRound = getPreference(PreferenceSetting.OpenReplayOnFirstRound); + autoStartNextRound = getPreference(PreferenceSetting.AutoStartNextRound); + autoStartSeconds = getPreference(PreferenceSetting.AutoStartSeconds); + popUpRoomsOnline = getPreference(PreferenceSetting.PopUpRooms); + checkForUpdates = getPreference(PreferenceSetting.CheckForUpdates); } private boolean confirmChangeOfDirectory() { - String originalReplayDirectory = prefs.get(PREFERENCES_STRING_REPLAY_DIRECTORY, System.getProperty("user.dir")); + String originalReplayDirectory = preferenceStore.get(PreferenceSetting.ReplayDirectory); File[] myExistingFiles = new File(originalReplayDirectory + "//Replays//" + ReplayFileUtil.FOLDER_PERSONAL_REPLAYS).listFiles(); int myExistingFilesLength = 0; diff --git a/client/src/main/java/screen/PreferencesPanelPlayers.java b/client/src/main/java/screen/PreferencesPanelPlayers.java index fc82bc20..be838b2d 100644 --- a/client/src/main/java/screen/PreferencesPanelPlayers.java +++ b/client/src/main/java/screen/PreferencesPanelPlayers.java @@ -32,6 +32,7 @@ import game.GameMode; import object.ApiStrategy; import object.LimitedDocument; +import preference.PreferenceSetting; import util.ApiUtil; import util.CpuStrategies; import util.Debug; @@ -39,6 +40,9 @@ import util.TableUtil; import util.TableUtil.DefaultModel; +import static preference.PreferenceSettingKt.getPreference; +import static util.ClientGlobals.preferenceStore; + public class PreferencesPanelPlayers extends AbstractPreferencesPanel implements MouseListener, ItemListener @@ -192,15 +196,15 @@ public void savePreferences() opponentTwoStrategy = (String) opponentTwoStrat.getSelectedItem(); opponentThreeStrategy = (String) opponentThreeStrat.getSelectedItem(); - prefs.put(PREFERENCES_STRING_PLAYER_NAME, playerName); - prefs.put(PREFERENCES_STRING_OPPONENT_ONE_NAME, opponentOneName); - prefs.put(PREFERENCES_STRING_OPPONENT_TWO_NAME, opponentTwoName); - prefs.put(PREFERENCES_STRING_OPPONENT_THREE_NAME, opponentThreeName); - prefs.putBoolean(PREFERENCES_BOOLEAN_OPPONENT_TWO_ENABLED, opponentTwoEnabled); - prefs.putBoolean(PREFERENCES_BOOLEAN_OPPONENT_THREE_ENABLED, opponentThreeEnabled); - prefs.put(PREFERENCES_STRING_OPPONENT_ONE_STRATEGY, opponentOneStrategy); - prefs.put(PREFERENCES_STRING_OPPONENT_TWO_STRATEGY, opponentTwoStrategy); - prefs.put(PREFERENCES_STRING_OPPONENT_THREE_STRATEGY, opponentThreeStrategy); + preferenceStore.save(PreferenceSetting.PlayerName, playerName); + preferenceStore.save(PreferenceSetting.OpponentOneName, opponentOneName); + preferenceStore.save(PreferenceSetting.OpponentTwoName, opponentTwoName); + preferenceStore.save(PreferenceSetting.OpponentThreeName, opponentThreeName); + preferenceStore.save(PreferenceSetting.OpponentTwoEnabled, opponentTwoEnabled); + preferenceStore.save(PreferenceSetting.OpponentThreeEnabled, opponentThreeEnabled); + preferenceStore.save(PreferenceSetting.OpponentOneStrategy, opponentOneStrategy); + preferenceStore.save(PreferenceSetting.OpponentTwoStrategy, opponentTwoStrategy); + preferenceStore.save(PreferenceSetting.OpponentThreeStrategy, opponentThreeStrategy); ApiUtil.saveApiStrategiesToPreferences(apiStrategies); } @@ -208,18 +212,18 @@ public void savePreferences() private void getVariablesFromPrefs() { - playerName = prefs.get(PREFERENCES_STRING_PLAYER_NAME, "Player"); - opponentOneName = prefs.get(PREFERENCES_STRING_OPPONENT_ONE_NAME, "Mark"); - opponentTwoName = prefs.get(PREFERENCES_STRING_OPPONENT_TWO_NAME, "Dave"); - opponentThreeName = prefs.get(PREFERENCES_STRING_OPPONENT_THREE_NAME, "Tom"); - opponentTwoEnabled = prefs.getBoolean(PREFERENCES_BOOLEAN_OPPONENT_TWO_ENABLED, true); - opponentThreeEnabled = prefs.getBoolean(PREFERENCES_BOOLEAN_OPPONENT_THREE_ENABLED, true); - opponentOneStrategy = prefs.get(PREFERENCES_STRING_OPPONENT_ONE_STRATEGY, "Basic"); - opponentTwoStrategy = prefs.get(PREFERENCES_STRING_OPPONENT_TWO_STRATEGY, "Basic"); - opponentThreeStrategy = prefs.get(PREFERENCES_STRING_OPPONENT_THREE_STRATEGY, "Basic"); + playerName = getPreference(PreferenceSetting.PlayerName); + opponentOneName = getPreference(PreferenceSetting.OpponentOneName); + opponentTwoName = getPreference(PreferenceSetting.OpponentTwoName); + opponentThreeName = getPreference(PreferenceSetting.OpponentThreeName); + opponentTwoEnabled = getPreference(PreferenceSetting.OpponentTwoEnabled); + opponentThreeEnabled = getPreference(PreferenceSetting.OpponentThreeEnabled); + opponentOneStrategy = getPreference(PreferenceSetting.OpponentOneStrategy); + opponentTwoStrategy = getPreference(PreferenceSetting.OpponentTwoStrategy); + opponentThreeStrategy = getPreference(PreferenceSetting.OpponentThreeStrategy); apiStrategies = ApiUtil.getApiStrategiesFromPreferences(); - gameMode = GameMode.valueOf(prefs.get(PREFERENCES_STRING_GAME_MODE, GameMode.Entropy.name())); + gameMode = GameMode.valueOf(getPreference(PreferenceSetting.GameMode)); } private void setPlayerNames() diff --git a/client/src/main/java/screen/ReplayDialog.java b/client/src/main/java/screen/ReplayDialog.java index 1a25d46c..591d66d1 100644 --- a/client/src/main/java/screen/ReplayDialog.java +++ b/client/src/main/java/screen/ReplayDialog.java @@ -34,13 +34,14 @@ import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument; +import bean.BidListCellRenderer; import game.PlayerAction; import game.Suit; -import object.BidListCellRenderer; import http.dto.OnlineMessage; import object.PlayerLabel; import online.screen.GameRoom; import online.screen.OnlineChatPanel; +import preference.PreferenceSetting; import screen.achievement.AchievementsDialog; import util.*; @@ -48,6 +49,8 @@ import static game.CardsUtilKt.isCardRelevant; import static game.RegistryUtilKt.populateActions; import static game.RenderingUtilKt.getVectropyResult; +import static preference.PreferenceSettingKt.*; +import static util.ClientGlobals.preferenceStore; import static utils.ColourUtilKt.getColourForPlayerNumber; import static utils.CoreGlobals.logger; @@ -57,9 +60,9 @@ public class ReplayDialog extends JFrame { public static final int RECENT_CHAT_MESSAGES_TO_SHOW = 10; - private String deckDirectory = Registry.DECK_DIRECTORY_CLASSIC; - private String jokerDirectory = Registry.JOKER_DIRECTORY_CLASSIC; - private String numberOfColours = ""; + private String deckDirectory = DECK_DESIGN_CLASSIC; + private String jokerDirectory = JOKER_DESIGN_CLASSIC; + private String numberOfColours = TWO_COLOURS; private int totalRounds = 0; private int roundNumber = 0; @@ -98,182 +101,175 @@ public class ReplayDialog extends JFrame public ReplayDialog() { - try - { - setSize(960, 480); - setLocationRelativeTo(null); - setResizable(false); - setIconImage(new ImageIcon(AchievementsDialog.class.getResource("/icons/replay.png")).getImage()); - getContentPane().setBackground(new Color(169, 169, 169)); - getContentPane().setLayout(null); - handsPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, SystemColor.scrollbar, new Color(105, 105, 105))); - handsPanel.setBackground(new Color(192, 192, 192)); - handsPanel.setBounds(50, 11, 489, 365); - getContentPane().add(handsPanel); - handsPanel.setLayout(null); - lblPlayer.setBounds(162, 206, 163, 23); - handsPanel.add(lblPlayer); - lblPlayer.setFont(new Font("Tahoma", Font.PLAIN, 15)); - lblPlayer.setHorizontalAlignment(SwingConstants.CENTER); - lblOpponentOne.setBounds(153, 10, 181, 23); - handsPanel.add(lblOpponentOne); - lblOpponentOne.setFont(new Font("Tahoma", Font.PLAIN, 15)); - lblOpponentOne.setHorizontalAlignment(SwingConstants.CENTER); - lblOpponentTwo.setBounds(-1, 37, 129, 23); - handsPanel.add(lblOpponentTwo); - lblOpponentTwo.setFont(new Font("Tahoma", Font.PLAIN, 15)); - lblOpponentTwo.setHorizontalAlignment(SwingConstants.CENTER); - lblOpponentThree.setBounds(358, 37, 129, 23); - handsPanel.add(lblOpponentThree); - lblOpponentThree.setHorizontalAlignment(SwingConstants.CENTER); - lblOpponentThree.setFont(new Font("Tahoma", Font.PLAIN, 15)); - panelOpponentTwoCards.setBounds(6, 67, 115, 232); - handsPanel.add(panelOpponentTwoCards); - panelOpponentTwoCards.setLayout(null); - opponentTwoCard5.setBounds(21, 117, 72, 96); - panelOpponentTwoCards.add(opponentTwoCard5); - opponentTwoCard4.setBounds(21, 92, 72, 96); - panelOpponentTwoCards.add(opponentTwoCard4); - opponentTwoCard3.setBounds(21, 67, 72, 96); - panelOpponentTwoCards.add(opponentTwoCard3); - opponentTwoCard2.setBounds(21, 42, 72, 96); - panelOpponentTwoCards.add(opponentTwoCard2); - opponentTwoCard1.setBounds(21, 17, 72, 96); - panelOpponentTwoCards.add(opponentTwoCard1); - panelOpponentThreeCards.setBounds(365, 67, 115, 232); - handsPanel.add(panelOpponentThreeCards); - panelOpponentThreeCards.setLayout(null); - opponentThreeCard5.setBounds(21, 117, 72, 96); - panelOpponentThreeCards.add(opponentThreeCard5); - opponentThreeCard4.setBounds(21, 92, 72, 96); - panelOpponentThreeCards.add(opponentThreeCard4); - opponentThreeCard3.setBounds(21, 67, 72, 96); - panelOpponentThreeCards.add(opponentThreeCard3); - opponentThreeCard2.setBounds(21, 42, 72, 96); - panelOpponentThreeCards.add(opponentThreeCard2); - opponentThreeCard1.setBounds(21, 17, 72, 96); - panelOpponentThreeCards.add(opponentThreeCard1); - panelOpponentCards.setBounds(127, 40, 232, 110); - handsPanel.add(panelOpponentCards); - panelOpponentCards.setLayout(new FlowLayout(FlowLayout.CENTER, -92, 5)); - opponentCard5.setPreferredSize(new Dimension(72, 96)); - panelOpponentCards.add(opponentCard5); - opponentCard4.setPreferredSize(new Dimension(72, 96)); - panelOpponentCards.add(opponentCard4); - opponentCard3.setPreferredSize(new Dimension(72, 96)); - panelOpponentCards.add(opponentCard3); - opponentCard2.setPreferredSize(new Dimension(72, 96)); - panelOpponentCards.add(opponentCard2); - opponentCard1.setPreferredSize(new Dimension(72, 96)); - panelOpponentCards.add(opponentCard1); - panelPlayerCards.setBounds(127, 235, 232, 110); - handsPanel.add(panelPlayerCards); - panelPlayerCards.setLayout(new FlowLayout(FlowLayout.CENTER, -92, 5)); - playerCard1.setPreferredSize(new Dimension(72, 96)); - panelPlayerCards.add(playerCard1); - playerCard2.setPreferredSize(new Dimension(72, 96)); - panelPlayerCards.add(playerCard2); - playerCard3.setPreferredSize(new Dimension(72, 96)); - panelPlayerCards.add(playerCard3); - playerCard4.setPreferredSize(new Dimension(72, 96)); - panelPlayerCards.add(playerCard4); - playerCard5.setPreferredSize(new Dimension(72, 96)); - panelPlayerCards.add(playerCard5); - lblOpponentOne.setVisible(false); - lblPlayer.setVisible(false); - separator.setBackground(SystemColor.scrollbar); - separator.setOrientation(1); - separator.setForeground(SystemColor.controlDkShadow); - separator.setBounds(589, 0, 10, 452); - getContentPane().add(separator); - lblBidHistory.setHorizontalAlignment(SwingConstants.CENTER); - lblBidHistory.setFont(new Font("Tahoma", Font.PLAIN, 17)); - lblBidHistory.setBounds(723, 15, 97, 23); - getContentPane().add(lblBidHistory); - scrollPane.setBounds(674, 42, 194, 144); - getContentPane().add(scrollPane); - history.setBackground(SystemColor.control); - history.setLocation(0, 119); - scrollPane.setViewportView(history); - history.setVisibleRowCount(4); - lblResult.setContentType("text/html"); - lblResult.setEditable(false); - lblResult.setFocusable(false); - lblResult.setFont(new Font("Tahoma", Font.PLAIN, 16)); - lblResult.setBounds(655, 200, 232, 46); - lblResult.setOpaque(false); - lblResult.setBorder(BorderFactory.createEmptyBorder()); - lblResult.setBackground(new Color(0,0,0,0)); - getContentPane().add(lblResult); - nextRound.setBounds(303, 387, 49, 48); - getContentPane().add(nextRound); - nextRound.setToolTipText("Next Round"); - previousRound.setBounds(244, 387, 49, 48); - getContentPane().add(previousRound); - previousRound.setToolTipText("Previous Round"); - setFilterIcons(); - clubFilter.setIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/clubFilterGreen.png"))); - clubFilter.setBackground(new Color(216, 191, 216)); - clubFilter.setFont(new Font("Times New Roman", Font.PLAIN, 24)); - clubFilter.setBounds(628, 275, 40, 40); - clubFilter.setMargin(new Insets(0, 0, 0, 0)); - getContentPane().add(clubFilter); - diamondFilter.setIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/diamondFilterBlue.png"))); - diamondFilter.setFont(new Font("Times New Roman", Font.PLAIN, 24)); - diamondFilter.setBounds(668, 275, 40, 40); - diamondFilter.setMargin(new Insets(0, 0, 0, 0)); - getContentPane().add(diamondFilter); - heartFilter.setFont(new Font("Times New Roman", Font.PLAIN, 24)); - heartFilter.setBounds(708, 275, 40, 40); - heartFilter.setMargin(new Insets(0, 0, 0, 0)); - getContentPane().add(heartFilter); - spadeFilter.setBackground(new Color(216, 191, 216)); - spadeFilter.setFont(new Font("Times New Roman", Font.PLAIN, 24)); - spadeFilter.setBounds(788, 275, 40, 40); - spadeFilter.setMargin(new Insets(0, 0, 0, 0)); - getContentPane().add(spadeFilter); - noFilter.setBackground(new Color(216, 191, 216)); - noFilter.setFont(new Font("Times New Roman", Font.BOLD, 24)); - noFilter.setBounds(868, 275, 40, 40); - noFilter.setMargin(new Insets(0, 0, 0, 0)); - getContentPane().add(noFilter); - lblFilter.setFont(new Font("Tahoma", Font.PLAIN, 14)); - lblFilter.setHorizontalAlignment(SwingConstants.CENTER); - lblFilter.setBounds(741, 245, 60, 22); - getContentPane().add(lblFilter); - filterGroup.add(noFilter); - filterGroup.add(clubFilter); - filterGroup.add(diamondFilter); - filterGroup.add(heartFilter); - filterGroup.add(spadeFilter); - filterGroup.add(moonFilter); - filterGroup.add(starFilter); - firstRound.setToolTipText("Previous Round"); - firstRound.setBounds(185, 387, 49, 48); - getContentPane().add(firstRound); - firstRound.setToolTipText("First Round"); - lastRound.setToolTipText("Previous Round"); - lastRound.setBounds(362, 387, 49, 48); - getContentPane().add(lastRound); - lastRound.setToolTipText("Last Round"); - chatPanel.setBounds(598, 340, 327, 100); - chatPanel.setBackground(SystemColor.control); - getContentPane().add(chatPanel); - moonFilter.setIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/moonFilterPurple.png"))); - moonFilter.setBounds(748, 275, 40, 40); - getContentPane().add(moonFilter); - starFilter.setSelectedIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/starFilterSelected.png"))); - starFilter.setIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/starFilter.png"))); - starFilter.setBounds(828, 275, 40, 40); - getContentPane().add(starFilter); - history.setCellRenderer(bidRenderer); + setSize(960, 480); + setLocationRelativeTo(null); + setResizable(false); + setIconImage(new ImageIcon(AchievementsDialog.class.getResource("/icons/replay.png")).getImage()); + getContentPane().setBackground(new Color(169, 169, 169)); + getContentPane().setLayout(null); + handsPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, SystemColor.scrollbar, new Color(105, 105, 105))); + handsPanel.setBackground(new Color(192, 192, 192)); + handsPanel.setBounds(50, 11, 489, 365); + getContentPane().add(handsPanel); + handsPanel.setLayout(null); + lblPlayer.setBounds(162, 206, 163, 23); + handsPanel.add(lblPlayer); + lblPlayer.setFont(new Font("Tahoma", Font.PLAIN, 15)); + lblPlayer.setHorizontalAlignment(SwingConstants.CENTER); + lblOpponentOne.setBounds(153, 10, 181, 23); + handsPanel.add(lblOpponentOne); + lblOpponentOne.setFont(new Font("Tahoma", Font.PLAIN, 15)); + lblOpponentOne.setHorizontalAlignment(SwingConstants.CENTER); + lblOpponentTwo.setBounds(-1, 37, 129, 23); + handsPanel.add(lblOpponentTwo); + lblOpponentTwo.setFont(new Font("Tahoma", Font.PLAIN, 15)); + lblOpponentTwo.setHorizontalAlignment(SwingConstants.CENTER); + lblOpponentThree.setBounds(358, 37, 129, 23); + handsPanel.add(lblOpponentThree); + lblOpponentThree.setHorizontalAlignment(SwingConstants.CENTER); + lblOpponentThree.setFont(new Font("Tahoma", Font.PLAIN, 15)); + panelOpponentTwoCards.setBounds(6, 67, 115, 232); + handsPanel.add(panelOpponentTwoCards); + panelOpponentTwoCards.setLayout(null); + opponentTwoCard5.setBounds(21, 117, 72, 96); + panelOpponentTwoCards.add(opponentTwoCard5); + opponentTwoCard4.setBounds(21, 92, 72, 96); + panelOpponentTwoCards.add(opponentTwoCard4); + opponentTwoCard3.setBounds(21, 67, 72, 96); + panelOpponentTwoCards.add(opponentTwoCard3); + opponentTwoCard2.setBounds(21, 42, 72, 96); + panelOpponentTwoCards.add(opponentTwoCard2); + opponentTwoCard1.setBounds(21, 17, 72, 96); + panelOpponentTwoCards.add(opponentTwoCard1); + panelOpponentThreeCards.setBounds(365, 67, 115, 232); + handsPanel.add(panelOpponentThreeCards); + panelOpponentThreeCards.setLayout(null); + opponentThreeCard5.setBounds(21, 117, 72, 96); + panelOpponentThreeCards.add(opponentThreeCard5); + opponentThreeCard4.setBounds(21, 92, 72, 96); + panelOpponentThreeCards.add(opponentThreeCard4); + opponentThreeCard3.setBounds(21, 67, 72, 96); + panelOpponentThreeCards.add(opponentThreeCard3); + opponentThreeCard2.setBounds(21, 42, 72, 96); + panelOpponentThreeCards.add(opponentThreeCard2); + opponentThreeCard1.setBounds(21, 17, 72, 96); + panelOpponentThreeCards.add(opponentThreeCard1); + panelOpponentCards.setBounds(127, 40, 232, 110); + handsPanel.add(panelOpponentCards); + panelOpponentCards.setLayout(new FlowLayout(FlowLayout.CENTER, -92, 5)); + opponentCard5.setPreferredSize(new Dimension(72, 96)); + panelOpponentCards.add(opponentCard5); + opponentCard4.setPreferredSize(new Dimension(72, 96)); + panelOpponentCards.add(opponentCard4); + opponentCard3.setPreferredSize(new Dimension(72, 96)); + panelOpponentCards.add(opponentCard3); + opponentCard2.setPreferredSize(new Dimension(72, 96)); + panelOpponentCards.add(opponentCard2); + opponentCard1.setPreferredSize(new Dimension(72, 96)); + panelOpponentCards.add(opponentCard1); + panelPlayerCards.setBounds(127, 235, 232, 110); + handsPanel.add(panelPlayerCards); + panelPlayerCards.setLayout(new FlowLayout(FlowLayout.CENTER, -92, 5)); + playerCard1.setPreferredSize(new Dimension(72, 96)); + panelPlayerCards.add(playerCard1); + playerCard2.setPreferredSize(new Dimension(72, 96)); + panelPlayerCards.add(playerCard2); + playerCard3.setPreferredSize(new Dimension(72, 96)); + panelPlayerCards.add(playerCard3); + playerCard4.setPreferredSize(new Dimension(72, 96)); + panelPlayerCards.add(playerCard4); + playerCard5.setPreferredSize(new Dimension(72, 96)); + panelPlayerCards.add(playerCard5); + lblOpponentOne.setVisible(false); + lblPlayer.setVisible(false); + separator.setBackground(SystemColor.scrollbar); + separator.setOrientation(1); + separator.setForeground(SystemColor.controlDkShadow); + separator.setBounds(589, 0, 10, 452); + getContentPane().add(separator); + lblBidHistory.setHorizontalAlignment(SwingConstants.CENTER); + lblBidHistory.setFont(new Font("Tahoma", Font.PLAIN, 17)); + lblBidHistory.setBounds(723, 15, 97, 23); + getContentPane().add(lblBidHistory); + scrollPane.setBounds(674, 42, 194, 144); + getContentPane().add(scrollPane); + history.setBackground(SystemColor.control); + history.setLocation(0, 119); + scrollPane.setViewportView(history); + history.setVisibleRowCount(4); + lblResult.setContentType("text/html"); + lblResult.setEditable(false); + lblResult.setFocusable(false); + lblResult.setFont(new Font("Tahoma", Font.PLAIN, 16)); + lblResult.setBounds(655, 200, 232, 46); + lblResult.setOpaque(false); + lblResult.setBorder(BorderFactory.createEmptyBorder()); + lblResult.setBackground(new Color(0,0,0,0)); + getContentPane().add(lblResult); + nextRound.setBounds(303, 387, 49, 48); + getContentPane().add(nextRound); + nextRound.setToolTipText("Next Round"); + previousRound.setBounds(244, 387, 49, 48); + getContentPane().add(previousRound); + previousRound.setToolTipText("Previous Round"); + setFilterIcons(); + clubFilter.setIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/clubFilterGreen.png"))); + clubFilter.setBackground(new Color(216, 191, 216)); + clubFilter.setFont(new Font("Times New Roman", Font.PLAIN, 24)); + clubFilter.setBounds(628, 275, 40, 40); + clubFilter.setMargin(new Insets(0, 0, 0, 0)); + getContentPane().add(clubFilter); + diamondFilter.setIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/diamondFilterBlue.png"))); + diamondFilter.setFont(new Font("Times New Roman", Font.PLAIN, 24)); + diamondFilter.setBounds(668, 275, 40, 40); + diamondFilter.setMargin(new Insets(0, 0, 0, 0)); + getContentPane().add(diamondFilter); + heartFilter.setFont(new Font("Times New Roman", Font.PLAIN, 24)); + heartFilter.setBounds(708, 275, 40, 40); + heartFilter.setMargin(new Insets(0, 0, 0, 0)); + getContentPane().add(heartFilter); + spadeFilter.setBackground(new Color(216, 191, 216)); + spadeFilter.setFont(new Font("Times New Roman", Font.PLAIN, 24)); + spadeFilter.setBounds(788, 275, 40, 40); + spadeFilter.setMargin(new Insets(0, 0, 0, 0)); + getContentPane().add(spadeFilter); + noFilter.setBackground(new Color(216, 191, 216)); + noFilter.setFont(new Font("Times New Roman", Font.BOLD, 24)); + noFilter.setBounds(868, 275, 40, 40); + noFilter.setMargin(new Insets(0, 0, 0, 0)); + getContentPane().add(noFilter); + lblFilter.setFont(new Font("Tahoma", Font.PLAIN, 14)); + lblFilter.setHorizontalAlignment(SwingConstants.CENTER); + lblFilter.setBounds(741, 245, 60, 22); + getContentPane().add(lblFilter); + filterGroup.add(noFilter); + filterGroup.add(clubFilter); + filterGroup.add(diamondFilter); + filterGroup.add(heartFilter); + filterGroup.add(spadeFilter); + filterGroup.add(moonFilter); + filterGroup.add(starFilter); + firstRound.setToolTipText("Previous Round"); + firstRound.setBounds(185, 387, 49, 48); + getContentPane().add(firstRound); + firstRound.setToolTipText("First Round"); + lastRound.setToolTipText("Previous Round"); + lastRound.setBounds(362, 387, 49, 48); + getContentPane().add(lastRound); + lastRound.setToolTipText("Last Round"); + chatPanel.setBounds(598, 340, 327, 100); + chatPanel.setBackground(SystemColor.control); + getContentPane().add(chatPanel); + moonFilter.setIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/moonFilterPurple.png"))); + moonFilter.setBounds(748, 275, 40, 40); + getContentPane().add(moonFilter); + starFilter.setSelectedIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/starFilterSelected.png"))); + starFilter.setIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/starFilter.png"))); + starFilter.setBounds(828, 275, 40, 40); + getContentPane().add(starFilter); + history.setCellRenderer(bidRenderer); - initialiseListeners(); - } - catch (Throwable t) - { - Debug.stackTrace(t); - } + initialiseListeners(); } private final BidListCellRenderer bidRenderer = new BidListCellRenderer(); @@ -435,22 +431,21 @@ private void initVariables() includeMoons = replay.getBoolean(REPLAY_BOOLEAN_INCLUDE_MOONS, false); includeStars = replay.getBoolean(REPLAY_BOOLEAN_INCLUDE_STARS, false); - deckDirectory = prefs.get(PREFERENCES_STRING_DECK_DIRECTORY, Registry.DECK_DIRECTORY_CLASSIC); - jokerDirectory = prefs.get(PREFERENCES_STRING_JOKER_DIRECTORY, Registry.JOKER_DIRECTORY_CLASSIC); - numberOfColours = prefs.get(PREFERENCES_STRING_NUMBER_OF_COLOURS, Registry.TWO_COLOURS); + deckDirectory = getPreference(PreferenceSetting.DeckDesign); + jokerDirectory = getPreference(PreferenceSetting.JokerDesign); + numberOfColours = getPreference(PreferenceSetting.NumberOfColours); } private int getStartOrEndRoundNumber() { - int openWhere = prefs.getInt(PREFERENCES_INT_REPLAY_DEFAULT, Registry.OPEN_ON_LAST_ROUND); - - if (openWhere == Registry.OPEN_ON_LAST_ROUND) + boolean openOnFirstRound = getPreference(PreferenceSetting.OpenReplayOnFirstRound); + if (openOnFirstRound) { - return totalRounds; + return 1; } else { - return 1; + return totalRounds; } } @@ -647,9 +642,6 @@ private void resetHandDisplay() private void displayHands() { - deckDirectory = prefs.get(PREFERENCES_STRING_DECK_DIRECTORY, Registry.DECK_DIRECTORY_CLASSIC); - numberOfColours = prefs.get(PREFERENCES_STRING_NUMBER_OF_COLOURS, Registry.TWO_COLOURS); - displayHand(playerCards, playerHand, playerNumberOfCards); displayHand(opponentOneCards, opponentOneHand, opponentOneNumberOfCards); displayHand(opponentTwoCards, opponentTwoHand, opponentTwoNumberOfCards); @@ -869,35 +861,28 @@ private void showPreviousHand() public void fireAppearancePreferencesChange() { - try + deckDirectory = getPreference(PreferenceSetting.DeckDesign); + jokerDirectory = getPreference(PreferenceSetting.JokerDesign); + numberOfColours = getPreference(PreferenceSetting.NumberOfColours); + + if (isVisible()) { - deckDirectory = prefs.get(PREFERENCES_STRING_DECK_DIRECTORY, Registry.DECK_DIRECTORY_CLASSIC); - jokerDirectory = prefs.get(PREFERENCES_STRING_JOKER_DIRECTORY, Registry.JOKER_DIRECTORY_CLASSIC); - numberOfColours = prefs.get(PREFERENCES_STRING_NUMBER_OF_COLOURS, Registry.TWO_COLOURS); - - if (isVisible()) + history.repaint(); + + Suit suitFiltered = getFilterSuitFromFilters(); + setFilterIcons(); + displayHands(); + highlightHands(suitFiltered); + + //if suitFiltered = -1, then show the result for lastBidSuitCode + if (suitFiltered == null) { - history.repaint(); - - Suit suitFiltered = getFilterSuitFromFilters(); - setFilterIcons(); - displayHands(); - highlightHands(suitFiltered); - - //if suitFiltered = -1, then show the result for lastBidSuitCode - if (suitFiltered == null) - { - showResult(lastBidSuit); - } - else - { - showResult(suitFiltered); - } + showResult(lastBidSuit); + } + else + { + showResult(suitFiltered); } - } - catch (Throwable t) - { - Debug.stackTrace(t); } } @@ -931,8 +916,7 @@ else if (starFilter.isSelected()) { private void setFilterIcons() { - numberOfColours = prefs.get(PREFERENCES_STRING_NUMBER_OF_COLOURS, Registry.TWO_COLOURS); - boolean fourColours = (numberOfColours.equals(Registry.FOUR_COLOURS)); + boolean fourColours = (numberOfColours.equals(FOUR_COLOURS)); heartFilter.setSelectedIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/heartFilterSelected.png"))); heartFilter.setIcon(new ImageIcon(ReplayDialog.class.getResource("/buttons/heartFilter.png"))); @@ -1005,64 +989,57 @@ private void initialiseListeners() @Override public void actionPerformed(ActionEvent arg0) { - try + Component source = (Component)arg0.getSource(); + if (source == firstRound) { - Component source = (Component)arg0.getSource(); - if (source == firstRound) - { - showFirstHand(); - } - else if (source == lastRound) - { - showLastHand(); - } - else if (source == nextRound) - { - showNextHand(); - } - else if (source == previousRound) - { - showPreviousHand(); - } - else if (source == clubFilter) - { - highlightHands(Suit.Clubs); - showResult(Suit.Clubs); - } - else if (source == diamondFilter) - { - highlightHands(Suit.Diamonds); - showResult(Suit.Diamonds); - } - else if (source == heartFilter) - { - highlightHands(Suit.Hearts); - showResult(Suit.Hearts); - } - else if (source == moonFilter) - { - highlightHands(Suit.Moons); - showResult(Suit.Moons); - } - else if (source == spadeFilter) - { - highlightHands(Suit.Spades); - showResult(Suit.Spades); - } - else if (source == starFilter) - { - highlightHands(Suit.Stars); - showResult(Suit.Stars); - } - else if (source == noFilter) - { - highlightHands(null); - showResult(lastBidSuit); - } + showFirstHand(); } - catch (Throwable t) + else if (source == lastRound) { - Debug.stackTrace(t); + showLastHand(); + } + else if (source == nextRound) + { + showNextHand(); + } + else if (source == previousRound) + { + showPreviousHand(); + } + else if (source == clubFilter) + { + highlightHands(Suit.Clubs); + showResult(Suit.Clubs); + } + else if (source == diamondFilter) + { + highlightHands(Suit.Diamonds); + showResult(Suit.Diamonds); + } + else if (source == heartFilter) + { + highlightHands(Suit.Hearts); + showResult(Suit.Hearts); + } + else if (source == moonFilter) + { + highlightHands(Suit.Moons); + showResult(Suit.Moons); + } + else if (source == spadeFilter) + { + highlightHands(Suit.Spades); + showResult(Suit.Spades); + } + else if (source == starFilter) + { + highlightHands(Suit.Stars); + showResult(Suit.Stars); + } + else if (source == noFilter) + { + highlightHands(null); + showResult(lastBidSuit); } } } \ No newline at end of file diff --git a/client/src/main/java/screen/ReplayInterface.java b/client/src/main/java/screen/ReplayInterface.java index 4b70c5b3..86d5bd20 100644 --- a/client/src/main/java/screen/ReplayInterface.java +++ b/client/src/main/java/screen/ReplayInterface.java @@ -4,6 +4,7 @@ import bean.FileUploadListener; import bean.FileUploader; import object.ReplayTable; +import preference.PreferenceSetting; import screen.achievement.AchievementsDialog; import util.DialogUtil; import util.Registry; @@ -21,6 +22,8 @@ import java.awt.event.WindowListener; import java.io.File; +import static preference.PreferenceSettingKt.getPreference; +import static util.ClientGlobals.preferenceStore; import static utils.CoreGlobals.logger; public class ReplayInterface extends JFrame @@ -190,7 +193,7 @@ private void setScrollpaneViewport(JScrollPane scrollPane, ReplayTable table, JL } else { - if (!prefs.getBoolean(PREFERENCES_BOOLEAN_SAVE_REPLAYS, false) + if (!getPreference(PreferenceSetting.SaveReplays) && table.getFolder().equals(ReplayFileUtil.FOLDER_PERSONAL_REPLAYS)) { replacementLabel.setText("Saving replays is currently disabled."); @@ -321,8 +324,8 @@ public void valueChanged(ListSelectionEvent e) public void windowClosing(WindowEvent e) { Dimension dim = this.getSize(); - prefs.putInt(PREFERENCES_INT_REPLAY_VIEWER_HEIGHT, dim.height); - prefs.putInt(PREFERENCES_INT_REPLAY_VIEWER_WIDTH, dim.width); + preferenceStore.save(PreferenceSetting.ReplayViewerHeight, dim.height); + preferenceStore.save(PreferenceSetting.ReplayViewerWidth, dim.width); } @Override diff --git a/client/src/main/java/screen/VectropyBidPanel.java b/client/src/main/java/screen/VectropyBidPanel.java index 0ff9258d..87622d0d 100644 --- a/client/src/main/java/screen/VectropyBidPanel.java +++ b/client/src/main/java/screen/VectropyBidPanel.java @@ -25,12 +25,16 @@ import javax.swing.event.ChangeListener; import achievement.Reward; +import game.RenderingUtilKt; import game.Suit; import game.VectropyBidAction; +import preference.PreferenceSetting; import util.Debug; import util.EntropyColour; import util.Registry; +import static preference.PreferenceSettingKt.getPreference; + public class VectropyBidPanel extends BidPanel implements ActionListener, ChangeListener, @@ -232,7 +236,7 @@ public void init(int maxBid, int totalNumberOfCards, boolean online, boolean inc starsPanel.setVisible(includeStars); totalCardsLabel.setText("x " + totalNumberOfCards); - String back = prefs.get(PREFERENCES_STRING_CARD_BACKS, Registry.BACK_CODE_CLASSIC_BLUE); + String back = getPreference(PreferenceSetting.CardBacks); smallCardIcon.setIcon(new ImageIcon(EntropyScreen.class.getResource("/backs/" + back + "Small.png"))); lastBid = null; @@ -265,9 +269,9 @@ private void setIllegalButtonState() private void updateSpinnerColours() { - clubLabel.setForeground(Suit.Clubs.getColour()); - diamondLabel.setForeground(Suit.Diamonds.getColour()); - moonLabel.setForeground(Suit.Moons.getColour()); + clubLabel.setForeground(RenderingUtilKt.getColour(Suit.Clubs)); + diamondLabel.setForeground(RenderingUtilKt.getColour(Suit.Diamonds)); + moonLabel.setForeground(RenderingUtilKt.getColour(Suit.Moons)); } private void setBidButtonState() @@ -292,7 +296,7 @@ private VectropyBidAction getBidFromSpinners() @Override public void fireAppearancePreferencesChange() { - String back = prefs.get(PREFERENCES_STRING_CARD_BACKS, Registry.BACK_CODE_CLASSIC_BLUE); + String back = getPreference(PreferenceSetting.CardBacks); smallCardIcon.setIcon(new ImageIcon(EntropyScreen.class.getResource("/backs/" + back + "Small.png"))); updateSpinnerColours(); @@ -324,7 +328,7 @@ public void loadState(Preferences savedGame) String label = savedGame.get(SAVED_GAME_STRING_TOTAL_CARDS_LABEL, "0"); totalCardsLabel.setText(label); - String back = prefs.get(PREFERENCES_STRING_CARD_BACKS, Registry.BACK_CODE_CLASSIC_BLUE); + String back = getPreference(PreferenceSetting.CardBacks); smallCardIcon.setIcon(new ImageIcon(EntropyScreen.class.getResource("/backs/" + back + "Small.png"))); } diff --git a/client/src/main/java/screen/VectropyScreen.java b/client/src/main/java/screen/VectropyScreen.java index 9d90c67d..e5f00178 100644 --- a/client/src/main/java/screen/VectropyScreen.java +++ b/client/src/main/java/screen/VectropyScreen.java @@ -5,12 +5,14 @@ import game.GameMode; import game.Suit; import game.VectropyBidAction; +import preference.PreferenceSetting; import util.AchievementsUtil; import util.Debug; import util.Registry; import static game.CheatUtilKt.getMaxBidString; import static game.RenderingUtilKt.getVectropyResult; +import static preference.PreferenceSettingKt.getPreference; public class VectropyScreen extends GameScreen { @@ -26,7 +28,7 @@ public VectropyScreen() setLayout(new BorderLayout(0, 0)); add(handPanel, BorderLayout.CENTER); handPanel.setOpaque(false); - bidPanel = new VectropyBidPanel(prefs.get(PREFERENCES_STRING_PLAYER_NAME, "Player"), handPanel); + bidPanel = new VectropyBidPanel(getPreference(PreferenceSetting.PlayerName), handPanel); add(bidPanel, BorderLayout.SOUTH); bidPanel.showBidPanel(false); diff --git a/client/src/main/java/util/AchievementsUtil.java b/client/src/main/java/util/AchievementsUtil.java index e384858a..dea20efa 100644 --- a/client/src/main/java/util/AchievementsUtil.java +++ b/client/src/main/java/util/AchievementsUtil.java @@ -18,7 +18,7 @@ import static achievement.AchievementUtilKt.unlockAchievement; import static util.ClientGlobals.achievementStore; -public class AchievementsUtil implements Registry +public class AchievementsUtil { private static final int FULL_GAME_STARTING_CARDS = 5; private static final int OMNISCIENT_THRESHOLD = 10; diff --git a/client/src/main/java/util/ApiUtil.java b/client/src/main/java/util/ApiUtil.java index 9044f023..2849b51b 100644 --- a/client/src/main/java/util/ApiUtil.java +++ b/client/src/main/java/util/ApiUtil.java @@ -8,6 +8,8 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import preference.PreferenceSetting; +import settings.Setting; import utils.CoreGlobals; import javax.swing.*; @@ -21,6 +23,9 @@ import java.net.SocketTimeoutException; import java.util.*; +import static preference.PreferenceSettingKt.getPreference; +import static util.ClientGlobals.preferenceStore; + public class ApiUtil implements Registry { public static final String API_PREFIX = "API: "; @@ -369,17 +374,17 @@ public static void saveStrategyErrorAndUnsetStrategies(ApiStrategy strategy, Str saveApiStrategiesToPreferences(apiStrategies); - resetCpuStrategy(PREFERENCES_STRING_OPPONENT_ONE_STRATEGY, name); - resetCpuStrategy(PREFERENCES_STRING_OPPONENT_TWO_STRATEGY, name); - resetCpuStrategy(PREFERENCES_STRING_OPPONENT_THREE_STRATEGY, name); + resetCpuStrategy(PreferenceSetting.OpponentOneStrategy, name); + resetCpuStrategy(PreferenceSetting.OpponentTwoStrategy, name); + resetCpuStrategy(PreferenceSetting.OpponentThreeStrategy, name); } - private static void resetCpuStrategy(String prefsKey, String apiName) + private static void resetCpuStrategy(Setting strategySetting, String apiName) { - String strategy = prefs.get(prefsKey, ""); + String strategy = getPreference(strategySetting); if (strategy.equals("API: " + apiName)) { - prefs.put(prefsKey, CpuStrategies.STRATEGY_BASIC); + preferenceStore.save(strategySetting, CpuStrategies.STRATEGY_BASIC); } } } diff --git a/client/src/main/java/util/ReplayConverter.java b/client/src/main/java/util/ReplayConverter.java index ed48acf5..4557563f 100644 --- a/client/src/main/java/util/ReplayConverter.java +++ b/client/src/main/java/util/ReplayConverter.java @@ -19,14 +19,6 @@ public class ReplayConverter implements Registry public static void startReplayConversionIfNecessary() { - String replayDirectory = prefs.get(PREFERENCES_STRING_REPLAY_DIRECTORY, null); - if (replayDirectory == null) - { - //Never ok'd the preferences dialog - basically a clean install. Nothing to do. - instance.putInt(INSTANCE_INT_REPLAY_CONVERSION, REPLAY_VERSION); - return; - } - int lastConvertedVersion = instance.getInt(INSTANCE_INT_REPLAY_CONVERSION, 0); if (lastConvertedVersion >= REPLAY_VERSION) { diff --git a/client/src/main/java/util/ReplayFileUtil.java b/client/src/main/java/util/ReplayFileUtil.java index cf09eb4d..6b2b2d69 100644 --- a/client/src/main/java/util/ReplayFileUtil.java +++ b/client/src/main/java/util/ReplayFileUtil.java @@ -5,6 +5,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import preference.PreferenceSetting; import screen.ReplayDialog; import java.io.File; @@ -20,6 +21,9 @@ import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; +import static preference.PreferenceSettingKt.getPreference; +import static util.ClientGlobals.preferenceStore; + public final class ReplayFileUtil implements Registry { public static final String FOLDER_PERSONAL_REPLAYS = "Personal"; @@ -115,7 +119,7 @@ public static void saveOnlineReplayToFile(String roomId, String username) private static void saveReplayToFile(Preferences replay) { - boolean save = prefs.getBoolean(PREFERENCES_BOOLEAN_SAVE_REPLAYS, false); + boolean save = getPreference(PreferenceSetting.SaveReplays); if (!save) { return; @@ -353,7 +357,7 @@ private static void addChatHistoryElement(Preferences replay, Document document, public static String getDirectoryFromPreferences() { - return prefs.get(PREFERENCES_STRING_REPLAY_DIRECTORY, System.getProperty("user.dir")); + return preferenceStore.get(PreferenceSetting.ReplayDirectory); } private static String factoryFileNameForReplay(Preferences replay) diff --git a/client/src/main/kotlin/bean/AchievementBadge.kt b/client/src/main/kotlin/bean/AchievementBadge.kt index 40045449..be562c01 100644 --- a/client/src/main/kotlin/bean/AchievementBadge.kt +++ b/client/src/main/kotlin/bean/AchievementBadge.kt @@ -5,10 +5,9 @@ import achievement.isUnlocked import java.awt.Dimension import javax.swing.JLabel import util.Images -import util.Registry import utils.Achievement -class AchievementBadge(private val achievement: Achievement) : JLabel(), Registry { +class AchievementBadge(private val achievement: Achievement) : JLabel() { val explanation = achievement.explanation val description = achievement.description diff --git a/client/src/main/kotlin/bean/BidListCellRenderer.kt b/client/src/main/kotlin/bean/BidListCellRenderer.kt new file mode 100644 index 00000000..e99e0d54 --- /dev/null +++ b/client/src/main/kotlin/bean/BidListCellRenderer.kt @@ -0,0 +1,67 @@ +package bean + +import game.BidAction +import game.MOONS_SYMBOL +import game.PlayerAction +import game.getCardHtml +import game.htmlString +import java.awt.Component +import javax.swing.DefaultListCellRenderer +import javax.swing.JList +import `object`.Player +import util.StringUtil + +class BidListCellRenderer : DefaultListCellRenderer() { + private var hmNameToColour: MutableMap = HashMap() + + override fun getListCellRendererComponent( + list: JList<*>?, + value: Any?, + index: Int, + isSelected: Boolean, + cellHasFocus: Boolean, + ): Component? { + val bid = value as PlayerAction + val text = toHtmlString(bid) + + return super.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus) + } + + fun updateColours(players: MutableCollection) { + this.hmNameToColour.clear() + + for (player in players) { + hmNameToColour.put(player.name, player.colour) + } + } + + fun updateColours(map: MutableMap) { + this.hmNameToColour = map + } + + fun toHtmlString(action: PlayerAction): String { + var playerName = action.playerName + playerName = StringUtil.escapeHtml(playerName) + + val colour = hmNameToColour.get(playerName) + var playerNamePrefix = playerName + ": " + + if (action.blind) { + playerNamePrefix = "[" + playerName + "]: " + } + + var text = "$playerNamePrefix" + text += action.htmlString() + + if (action is BidAction<*> && action.cardToReveal != null) { + text += "&emsp(Shows: " + text += getCardHtml(action.cardToReveal!!) + text += ")" + } + + // The unicode for a moon doesn't work in HTML. Also shrink to match the size of the other + // suits. + text = text.replace(MOONS_SYMBOL.toRegex(), "🌙") + return text + } +} diff --git a/client/src/main/kotlin/game/RenderingUtil.kt b/client/src/main/kotlin/game/RenderingUtil.kt index 3db955cd..458e2389 100644 --- a/client/src/main/kotlin/game/RenderingUtil.kt +++ b/client/src/main/kotlin/game/RenderingUtil.kt @@ -1,5 +1,11 @@ package game +import java.awt.Color +import preference.FOUR_COLOURS +import preference.PreferenceSetting +import util.ClientGlobals +import utils.toHexCode + fun getCardHtml(card: String): String { if (card.contains("Jo")) { return "Jo" @@ -26,3 +32,17 @@ fun getVectropyResult( return "(${htmlStrings.joinToString(", ")})" } + +fun PlayerAction.htmlString() = + when (this) { + is EntropyBidAction -> + "$amount${suit.unicodeStr}" + else -> plainString() + } + +fun Suit.getColour(): Color { + val numberOfColoursStr = ClientGlobals.preferenceStore.get(PreferenceSetting.NumberOfColours) + return if (numberOfColoursStr == FOUR_COLOURS) fourColour else twoColour +} + +fun Suit.getColourHex() = getColour().toHexCode() diff --git a/client/src/main/kotlin/help/HelpPanel.kt b/client/src/main/kotlin/help/HelpPanel.kt index 936d04c5..cf1575af 100644 --- a/client/src/main/kotlin/help/HelpPanel.kt +++ b/client/src/main/kotlin/help/HelpPanel.kt @@ -10,9 +10,11 @@ import javax.swing.JPanel import javax.swing.JTextPane import javax.swing.text.DefaultHighlighter.DefaultHighlightPainter import javax.swing.text.Highlighter +import preference.FOUR_COLOURS +import preference.PreferenceSetting import screen.HelpDialog import screen.ScreenCache -import util.Registry +import util.ClientGlobals.preferenceStore import utils.CoreGlobals.logger import utils.getAllChildComponentsForType @@ -223,8 +225,7 @@ abstract class HelpPanel : JPanel() { override fun toString() = nodeName protected fun useFourColours() = - Registry.prefs[Registry.PREFERENCES_STRING_NUMBER_OF_COLOURS, Registry.TWO_COLOURS] == - Registry.FOUR_COLOURS + preferenceStore.get(PreferenceSetting.NumberOfColours) == FOUR_COLOURS open fun refresh() { // to be overridden by any pages that have dynamic content diff --git a/client/src/main/kotlin/preference/PreferenceSetting.kt b/client/src/main/kotlin/preference/PreferenceSetting.kt index cf400247..2803357f 100644 --- a/client/src/main/kotlin/preference/PreferenceSetting.kt +++ b/client/src/main/kotlin/preference/PreferenceSetting.kt @@ -1,3 +1,66 @@ package preference -object PreferenceSetting {} +import settings.Setting +import util.ClientGlobals.preferenceStore +import util.CpuStrategies.STRATEGY_BASIC + +const val TWO_COLOURS = "twocolour" +const val FOUR_COLOURS = "fourcolour" +const val DECK_DESIGN_CLASSIC = "classic" +const val DECK_DESIGN_ALTERNATE = "alternate" +const val JOKER_DESIGN_CLASSIC = "classic" +const val JOKER_DESIGN_DEVELOPERS = "developers" + +const val GAME_SPEED_SLOW = 1500 +const val GAME_SPEED_MEDIUM = 1000 +const val GAME_SPEED_FAST = 500 + +fun getPreference(setting: Setting) = preferenceStore.get(setting) + +object PreferenceSetting { + // Gameplay + @JvmField val GameMode = Setting("gameMode", game.GameMode.Entropy.name) + @JvmField val PlayWithHandicap = Setting("playWithHandicap", false) + @JvmField val HandicapAmount = Setting("handicapAmount", 1) + @JvmField val PlayBlind = Setting("playBlind", false) + + // Players + @JvmField val PlayerName = Setting("playerName", "Player") + @JvmField val OpponentOneName = Setting("opponentOneName", "Mark") + @JvmField val OpponentTwoName = Setting("opponentTwoName", "David") + @JvmField val OpponentThreeName = Setting("opponentThreeName", "Tom") + @JvmField val OpponentOneStrategy = Setting("opponentOneStrategy", STRATEGY_BASIC) + @JvmField val OpponentTwoStrategy = Setting("opponentTwoStrategy", STRATEGY_BASIC) + @JvmField val OpponentThreeStrategy = Setting("opponentThreeStrategy", STRATEGY_BASIC) + @JvmField val OpponentTwoEnabled = Setting("opponentTwoEnabled", false) + @JvmField val OpponentThreeEnabled = Setting("opponentThreeEnabled", false) + + // Appearance + @JvmField val DeckDesign = Setting("deckDesign", DECK_DESIGN_CLASSIC) + @JvmField val JokerDesign = Setting("jokerDesign", JOKER_DESIGN_CLASSIC) + @JvmField val NumberOfColours = Setting("numberOfColours", TWO_COLOURS) + @JvmField val CardBacks = Setting("cardBacks", "backBlue") + @JvmField val LookAndFeel = Setting("lookAndFeel", "Metal") + + // Misc + @JvmField val SaveReplays = Setting("saveReplays", false) + @JvmField val ReplayDirectory = Setting("replayDirectory", System.getProperty("user.dir")) + @JvmField val OpenReplayOnFirstRound = Setting("openReplayOnFirstRound", false) + @JvmField val GameSpeed = Setting("gameSpeed", GAME_SPEED_MEDIUM) + @JvmField val AutoSave = Setting("autoSave", false) + @JvmField val AutoStartNextRound = Setting("autoStartNextRound", false) + @JvmField val AutoStartSeconds = Setting("autoStartSeconds", 2) + @JvmField val PopUpRooms = Setting("popUpRooms", true) + @JvmField val CheckForUpdates = Setting("checkForUpdates", true) + + // Replay table preferences + @JvmField val IncludeGameModeColumn = Setting("includeGameModeColumn", true) + @JvmField val IncludeRoundsColumn = Setting("includeRoundsColumn", false) + @JvmField val IncludePlayersColumn = Setting("includePlayersColumn", true) + @JvmField val IncludeCardsColumn = Setting("includeCardsColumn", false) + @JvmField val IncludeRoomNameColumn = Setting("includeRoomNameColumn", false) + + // Invisible preferences + @JvmField val ReplayViewerHeight = Setting("rvheight", 475) + @JvmField val ReplayViewerWidth = Setting("rvwidth", 875) +} diff --git a/client/src/main/kotlin/screen/preference/PreferencesDialog.kt b/client/src/main/kotlin/screen/preference/PreferencesDialog.kt index 70fb86e6..8a66a198 100644 --- a/client/src/main/kotlin/screen/preference/PreferencesDialog.kt +++ b/client/src/main/kotlin/screen/preference/PreferencesDialog.kt @@ -14,10 +14,9 @@ import screen.PreferencesPanelMisc import screen.PreferencesPanelPlayers import screen.SimpleDialog import util.ApiUtil -import util.Registry import utils.getAllChildComponentsForType -class PreferencesDialog : SimpleDialog(), Registry { +class PreferencesDialog : SimpleDialog() { private val tabbedPane = JTabbedPane(SwingConstants.TOP) private val gameplayPanel = PreferencesPanelGameplay() private val appearanceScrollPane = JScrollPane() diff --git a/client/src/main/kotlin/settings/AbstractSettingStore.kt b/client/src/main/kotlin/settings/AbstractSettingStore.kt index fa0d57ec..f2590b22 100644 --- a/client/src/main/kotlin/settings/AbstractSettingStore.kt +++ b/client/src/main/kotlin/settings/AbstractSettingStore.kt @@ -36,10 +36,10 @@ abstract class AbstractSettingStore { return setting.default } - val raw = findRaw(setting) ?: return setting.default - return convertFromRaw(setting, raw) + return find(setting) ?: return setting.default } + // TODO - Replace with inline fns and json serialisation private fun toRawValue(raw: T) = raw.toString() @Suppress("UNCHECKED_CAST") diff --git a/client/src/test/kotlin/util/AbstractClientTest.kt b/client/src/test/kotlin/util/AbstractClientTest.kt index 01d9e154..9878768a 100644 --- a/client/src/test/kotlin/util/AbstractClientTest.kt +++ b/client/src/test/kotlin/util/AbstractClientTest.kt @@ -13,6 +13,7 @@ abstract class AbstractClientTest : AbstractTest() { fun beforeEach() { ClientGlobals.achievementStore = InMemorySettingStore() ClientGlobals.rewardStore = InMemorySettingStore() + ClientGlobals.preferenceStore = InMemorySettingStore() ScreenCache.emptyCache() } diff --git a/core/src/main/java/util/Registry.java b/core/src/main/java/util/Registry.java index 40bb5522..7ad3a820 100644 --- a/core/src/main/java/util/Registry.java +++ b/core/src/main/java/util/Registry.java @@ -33,43 +33,6 @@ public interface Registry public static final String SHARED_INT_NUMBER_OF_CARDS = "numberOfCards"; //prefs - public static final String PREFERENCES_STRING_REPLAY_DIRECTORY = "replayDirectory"; - public static final String PREFERENCES_STRING_DECK_DIRECTORY = "deckDirectory"; - public static final String PREFERENCES_STRING_JOKER_DIRECTORY = "jokerDirectory"; - public static final String PREFERENCES_STRING_NUMBER_OF_COLOURS = "numberOfColours"; - public static final String PREFERENCES_STRING_CARD_BACKS = "cardBacks"; - public static final String PREFERENCES_STRING_LOOK_AND_FEEL = "lookAndFeel"; - public static final String PREFERENCES_STRING_OPPONENT_THREE_STRATEGY = "opponentThreeStrategy"; - public static final String PREFERENCES_STRING_OPPONENT_TWO_STRATEGY = "opponentTwoStrategy"; - public static final String PREFERENCES_STRING_OPPONENT_ONE_STRATEGY = "opponentOneStrategy"; - public static final String PREFERENCES_STRING_OPPONENT_THREE_NAME = "opponentThreeName"; - public static final String PREFERENCES_STRING_OPPONENT_TWO_NAME = "opponentTwoName"; - public static final String PREFERENCES_STRING_OPPONENT_ONE_NAME = "opponentOneName"; - public static final String PREFERENCES_STRING_PLAYER_NAME = "playerName"; - - public static final String PREFERENCES_BOOLEAN_SAVE_REPLAYS = "saveReplays"; - public static final String PREFERENCES_BOOLEAN_AUTOSAVE = "autosave"; - public static final String PREFERENCES_BOOLEAN_AUTO_START_NEXT_ROUND = "autoStart"; - public static final String PREFERENCES_BOOLEAN_POP_UP_ROOMS = "popUp"; - public static final String PREFERENCES_BOOLEAN_OPPONENT_THREE_ENABLED = "opponentThreeEnabled"; - public static final String PREFERENCES_BOOLEAN_OPPONENT_TWO_ENABLED = "opponentTwoEnabled"; - public static final String PREFERENCES_BOOLEAN_PLAY_BLIND = "playBlind"; - public static final String PREFERENCES_BOOLEAN_PLAY_WITH_HANDICAP = "playWithHandicap"; - public static final String PREFERENCES_BOOLEAN_INCLUDE_GAME_MODE_COLUMN = "includeMode"; - public static final String PREFERENCES_BOOLEAN_INCLUDE_ROUNDS_COLUMN = "includeRounds"; - public static final String PREFERENCES_BOOLEAN_INCLUDE_PLAYERS_COLUMN = "includePlayers"; - public static final String PREFERENCES_BOOLEAN_INCLUDE_CARDS_COLUMN = "includeCards"; - public static final String PREFERENCES_BOOLEAN_INCLUDE_ROOM_NAME_COLUMN = "includeRoomName"; - public static final String PREFERENCES_BOOLEAN_CHECK_FOR_UPDATES = "checkForUpdates"; - - public static final String PREFERENCES_INT_REPLAY_DEFAULT = "replayDefault"; - public static final String PREFERENCES_INT_GAME_SPEED = "gameSpeed"; - public static final String PREFERENCES_INT_AUTO_START_SECONDS = "autoStartMillis"; - public static final String PREFERENCES_INT_HANDICAP_AMOUNT = "handicapAmount"; - public static final String PREFERENCES_INT_REPLAY_VIEWER_HEIGHT = "rvheight"; - public static final String PREFERENCES_INT_REPLAY_VIEWER_WIDTH = "rvwidth"; - public static final String PREFERENCES_STRING_GAME_MODE = "gameMode"; - public static final String PREFERENCES_XML_API_SETTINGS = "apiSettings"; public static final String PREFERENCES_TAG_API = "Api"; public static final String PREFERENCES_ATTR_API_NAME = "ApiName"; @@ -189,14 +152,5 @@ public interface Registry public static final String SAVED_GAME_STRING_GAME_MODE = "gameMode"; //statics for default values etc - public static final String TWO_COLOURS = "twocolour"; - public static final String FOUR_COLOURS = "fourcolour"; - public static final String DECK_DIRECTORY_CLASSIC = "classic"; - public static final String DECK_DIRECTORY_ALTERNATE = "alternate"; - public static final String JOKER_DIRECTORY_CLASSIC = "classic"; - public static final String JOKER_DIRECTORY_DEVELOPERS = "developers"; public static final String BACK_CODE_CLASSIC_BLUE = "backBlue"; - public static final String DEFAULT_LOOK_AND_FEEL = "Metal"; - public static final int OPEN_ON_FIRST_ROUND = 0; - public static final int OPEN_ON_LAST_ROUND = 1; } \ No newline at end of file diff --git a/core/src/main/kotlin/game/EntropyBidAction.kt b/core/src/main/kotlin/game/EntropyBidAction.kt index 906afae5..e7bedc97 100644 --- a/core/src/main/kotlin/game/EntropyBidAction.kt +++ b/core/src/main/kotlin/game/EntropyBidAction.kt @@ -31,9 +31,6 @@ data class EntropyBidAction( override fun plainString() = "$amount ${suit.getDescription(amount)}" - override fun htmlString() = - "$amount${suit.unicodeStr}" - companion object { @JvmStatic fun fromJson(jsonString: String): EntropyBidAction = diff --git a/core/src/main/kotlin/game/PlayerAction.kt b/core/src/main/kotlin/game/PlayerAction.kt index 2170ab93..7f409a66 100644 --- a/core/src/main/kotlin/game/PlayerAction.kt +++ b/core/src/main/kotlin/game/PlayerAction.kt @@ -22,7 +22,5 @@ abstract class PlayerAction { abstract fun plainString(): String - open fun htmlString() = plainString() - fun toJsonString(): String = CoreGlobals.jsonMapper.writeValueAsString(this) } diff --git a/core/src/main/kotlin/game/Suit.kt b/core/src/main/kotlin/game/Suit.kt index e341c014..14fdadb9 100644 --- a/core/src/main/kotlin/game/Suit.kt +++ b/core/src/main/kotlin/game/Suit.kt @@ -1,11 +1,9 @@ package game import java.awt.Color -import util.Registry import utils.COLOUR_SUIT_GOLD import utils.COLOUR_SUIT_GREEN import utils.COLOUR_SUIT_PURPLE -import utils.toHexCode const val CLUBS_SYMBOL = "\u2663" const val DIAMONDS_SYMBOL = "\u2666" @@ -33,14 +31,6 @@ enum class Suit( return if (singular) lower.dropLast(1) else lower } - fun getColour(): Color { - val numberOfColoursStr = - Registry.prefs[Registry.PREFERENCES_STRING_NUMBER_OF_COLOURS, Registry.TWO_COLOURS] - return if (numberOfColoursStr == Registry.FOUR_COLOURS) fourColour else twoColour - } - - fun getColourHex() = getColour().toHexCode() - fun lessThan(other: Suit) = this < other fun next(includeMoons: Boolean, includeStars: Boolean): Suit { diff --git a/core/src/test/kotlin/game/EntropyBidActionTest.kt b/core/src/test/kotlin/game/EntropyBidActionTest.kt index fd27a63a..27685262 100644 --- a/core/src/test/kotlin/game/EntropyBidActionTest.kt +++ b/core/src/test/kotlin/game/EntropyBidActionTest.kt @@ -1,13 +1,11 @@ package game import io.kotest.matchers.shouldBe -import java.awt.Color import org.junit.jupiter.api.Test import testCore.AbstractTest import testCore.makeEntropyBidAction import testCore.makeGameSettings import utils.CoreGlobals -import utils.toHexCode class EntropyBidActionTest : AbstractTest() { @Test @@ -70,8 +68,5 @@ class EntropyBidActionTest : AbstractTest() { fun `Should have sensible description`() { makeEntropyBidAction(1, Suit.Diamonds).plainString() shouldBe "1 diamond" makeEntropyBidAction(3, Suit.Diamonds).plainString() shouldBe "3 diamonds" - - makeEntropyBidAction(1, Suit.Hearts).htmlString() shouldBe - "1♥" } } diff --git a/core/src/test/kotlin/game/VectropyBidActionTest.kt b/core/src/test/kotlin/game/VectropyBidActionTest.kt index 6a819918..97203c44 100644 --- a/core/src/test/kotlin/game/VectropyBidActionTest.kt +++ b/core/src/test/kotlin/game/VectropyBidActionTest.kt @@ -108,7 +108,6 @@ class VectropyBidActionTest : AbstractTest() { val allSuits = coreSuits + mapOf(Suit.Moons to 7, Suit.Stars to 9) VectropyBidAction("", false, allSuits).plainString() shouldBe "(3, 0, 2, 7, 1, 9)" - VectropyBidAction("", false, allSuits).htmlString() shouldBe "(3, 0, 2, 7, 1, 9)" } @Test From 1a6b8d16c3e8b423987556eb1a20c3d739c7c911 Mon Sep 17 00:00:00 2001 From: alyssa Date: Wed, 27 Aug 2025 08:39:36 +0100 Subject: [PATCH 06/13] port preference panels to kotlin --- .../java/screen/AbstractPreferencesPanel.java | 34 -- .../screen/PreferencesPanelAppearance.java | 430 ---------------- .../java/screen/PreferencesPanelGameplay.java | 338 ------------- .../java/screen/PreferencesPanelMisc.java | 305 ------------ .../java/screen/PreferencesPanelPlayers.java | 468 ------------------ client/src/main/java/util/ApiUtil.java | 7 +- client/src/main/java/util/CpuStrategies.java | 4 +- .../preference/AbstractPreferencesPanel.kt | 27 + .../screen/preference/PreferencesDialog.kt | 26 +- .../preference/PreferencesPanelAppearance.kt | 397 +++++++++++++++ .../preference/PreferencesPanelGameplay.kt | 303 ++++++++++++ .../screen/preference/PreferencesPanelMisc.kt | 281 +++++++++++ .../preference/PreferencesPanelPlayers.kt | 374 ++++++++++++++ core/src/main/java/util/Debug.java | 1 + 14 files changed, 1398 insertions(+), 1597 deletions(-) delete mode 100644 client/src/main/java/screen/AbstractPreferencesPanel.java delete mode 100644 client/src/main/java/screen/PreferencesPanelAppearance.java delete mode 100644 client/src/main/java/screen/PreferencesPanelGameplay.java delete mode 100644 client/src/main/java/screen/PreferencesPanelMisc.java delete mode 100644 client/src/main/java/screen/PreferencesPanelPlayers.java create mode 100644 client/src/main/kotlin/screen/preference/AbstractPreferencesPanel.kt create mode 100644 client/src/main/kotlin/screen/preference/PreferencesPanelAppearance.kt create mode 100644 client/src/main/kotlin/screen/preference/PreferencesPanelGameplay.kt create mode 100644 client/src/main/kotlin/screen/preference/PreferencesPanelMisc.kt create mode 100644 client/src/main/kotlin/screen/preference/PreferencesPanelPlayers.kt diff --git a/client/src/main/java/screen/AbstractPreferencesPanel.java b/client/src/main/java/screen/AbstractPreferencesPanel.java deleted file mode 100644 index 268f680a..00000000 --- a/client/src/main/java/screen/AbstractPreferencesPanel.java +++ /dev/null @@ -1,34 +0,0 @@ -package screen; - -import achievement.Reward; -import screen.preference.PreferencesDialog; -import util.Registry; - -import javax.swing.*; -import java.awt.event.ActionListener; - -public abstract class AbstractPreferencesPanel extends JPanel - implements ActionListener -{ - protected PreferencesDialog parent = null; - - public abstract void initVariables(); - public abstract boolean valid(); - public abstract void savePreferences(); - - protected void toggleLockedComponent(AbstractButton c, Reward requiredReward) - { - boolean unlocked = requiredReward.isUnlocked(); - String text = unlocked? c.getText() : "Locked"; - String toolTipText = unlocked? c.getToolTipText() : "Unlock at " + requiredReward.getThreshold() + " achievements"; - - c.setText(text); - c.setToolTipText(toolTipText); - c.setEnabled(unlocked); - } - - public void setParent(PreferencesDialog parent) - { - this.parent = parent; - } -} diff --git a/client/src/main/java/screen/PreferencesPanelAppearance.java b/client/src/main/java/screen/PreferencesPanelAppearance.java deleted file mode 100644 index e1e0e6cd..00000000 --- a/client/src/main/java/screen/PreferencesPanelAppearance.java +++ /dev/null @@ -1,430 +0,0 @@ -package screen; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.util.Vector; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.ComboBoxModel; -import javax.swing.DefaultComboBoxModel; -import javax.swing.ImageIcon; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JSeparator; -import javax.swing.JTextPane; -import javax.swing.SwingConstants; -import javax.swing.UIManager; -import javax.swing.UIManager.LookAndFeelInfo; -import javax.swing.border.LineBorder; -import javax.swing.text.DefaultCaret; - -import achievement.Reward; -import bean.ComboBoxItem; -import object.DisabledComboBoxModel; -import preference.PreferenceSetting; -import util.GameUtil; - -import static preference.PreferenceSettingKt.*; -import static util.ClientGlobals.preferenceStore; - -public class PreferencesPanelAppearance extends AbstractPreferencesPanel - implements ItemListener -{ - private String deckDesign = ""; - private String jokerDesign = ""; - private String cardBacks = ""; - private String numberOfColours = ""; - private String lookAndFeel = ""; - - public PreferencesPanelAppearance() - { - setPreferredSize(new Dimension(400, 760)); - setLayout(null); - - bgDeckDesign.add(rdbtnClassicDesign); - bgDeckDesign.add(rdbtnMinimalistDesign); - bgJokerDesign.add(rdbtnClassicJokers); - bgJokerDesign.add(rdbtnDeveloperJokers); - deckDesignPanel.setBounds(17, 80, 374, 58); - add(deckDesignPanel); - deckDesignPanel.setBorder(new LineBorder(Color.GRAY)); - deckDesignPanel.setLayout(null); - rdbtnClassicDesign.setBounds(6, 30, 72, 23); - deckDesignPanel.add(rdbtnClassicDesign); - rdbtnMinimalistDesign.setBounds(80, 30, 146, 23); - deckDesignPanel.add(rdbtnMinimalistDesign); - deckDesignPanel.add(lblCardDesign); - deckPreviewPanel.setBounds(17, 137, 374, 136); - add(deckPreviewPanel); - deckPreviewPanel.setBorder(new LineBorder(Color.GRAY)); - deckPreviewPanel.setLayout(null); - labelKh.setBounds(187, 20, 72, 96); - deckPreviewPanel.add(labelKh); - labelJc.setBounds(43, 20, 72, 96); - deckPreviewPanel.add(labelJc); - labelQd.setBounds(115, 20, 72, 96); - deckPreviewPanel.add(labelQd); - labelAs.setBounds(259, 20, 72, 96); - deckPreviewPanel.add(labelAs); - lblCardDesign.setHorizontalAlignment(SwingConstants.CENTER); - lblCardDesign.setFont(new Font("Tahoma", Font.BOLD, 14)); - lblCardDesign.setBounds(131, 8, 113, 17); - lblVisualPreferences.setHorizontalAlignment(SwingConstants.CENTER); - lblVisualPreferences.setBounds(178, 12, 72, 17); - add(lblVisualPreferences); - lblVisualPreferences.setFont(new Font("Tahoma", Font.PLAIN, 14)); - add(separator_1); - jokerDesignPanel.setLayout(null); - jokerDesignPanel.setBorder(new LineBorder(Color.GRAY)); - jokerDesignPanel.setBounds(17, 288, 374, 58); - add(jokerDesignPanel); - rdbtnClassicJokers.setBounds(6, 30, 72, 23); - jokerDesignPanel.add(rdbtnClassicJokers); - rdbtnDeveloperJokers.setBounds(80, 30, 102, 23); - jokerDesignPanel.add(rdbtnDeveloperJokers); - separator_1.setBounds(0, 38, 429, 2); - lblJokerDesign.setHorizontalAlignment(SwingConstants.CENTER); - lblJokerDesign.setFont(new Font("Tahoma", Font.BOLD, 14)); - lblJokerDesign.setBounds(136, 8, 102, 17); - jokerDesignPanel.add(lblJokerDesign); - jokerPreviewPanel.setLayout(null); - jokerPreviewPanel.setBorder(new LineBorder(Color.GRAY)); - jokerPreviewPanel.setBounds(17, 345, 374, 136); - add(jokerPreviewPanel); - labelJo2.setBounds(187, 20, 72, 96); - jokerPreviewPanel.add(labelJo2); - labelJo0.setBounds(43, 20, 72, 96); - jokerPreviewPanel.add(labelJo0); - labelJo1.setBounds(115, 20, 72, 96); - jokerPreviewPanel.add(labelJo1); - labelJo3.setBounds(259, 20, 72, 96); - jokerPreviewPanel.add(labelJo3); - cbFourColour.setBounds(17, 48, 135, 23); - add(cbFourColour); - backDesignPanel.setLayout(null); - backDesignPanel.setBorder(new LineBorder(Color.GRAY)); - backDesignPanel.setBounds(17, 496, 374, 114); - add(backDesignPanel); - lblCardBacks.setHorizontalAlignment(SwingConstants.CENTER); - lblCardBacks.setFont(new Font("Tahoma", Font.BOLD, 14)); - lblCardBacks.setBounds(127, 8, 102, 17); - backDesignPanel.add(lblCardBacks); - labelBack.setBounds(23, 9, 72, 96); - backDesignPanel.add(labelBack); - comboBoxBacks.setBounds(121, 46, 190, 22); - backDesignPanel.add(comboBoxBacks); - panelLookAndFeel.setLayout(null); - panelLookAndFeel.setBorder(new LineBorder(Color.GRAY)); - panelLookAndFeel.setBounds(17, 625, 374, 114); - add(panelLookAndFeel); - lblLookFeel.setHorizontalAlignment(SwingConstants.CENTER); - lblLookFeel.setFont(new Font("Tahoma", Font.BOLD, 14)); - lblLookFeel.setBounds(127, 8, 102, 17); - panelLookAndFeel.add(lblLookFeel); - comboBoxLookAndFeel.setBounds(86, 81, 190, 22); - panelLookAndFeel.add(comboBoxLookAndFeel); - DefaultCaret caret = new DefaultCaret(); - caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE); - txtpnLookAndFeelDisclaimer.setCaret(caret); - txtpnLookAndFeelDisclaimer.setText("Note: These options are experimental. You will need to restart for this to take effect."); - txtpnLookAndFeelDisclaimer.setBounds(10, 28, 354, 40); - txtpnLookAndFeelDisclaimer.setOpaque(false); - txtpnLookAndFeelDisclaimer.setBorder(BorderFactory.createEmptyBorder()); - txtpnLookAndFeelDisclaimer.setBackground(new Color(0,0,0,0)); - txtpnLookAndFeelDisclaimer.setEditable(false); - panelLookAndFeel.add(txtpnLookAndFeelDisclaimer); - - rdbtnClassicDesign.addActionListener(this); - rdbtnMinimalistDesign.addActionListener(this); - rdbtnClassicJokers.addActionListener(this); - rdbtnDeveloperJokers.addActionListener(this); - comboBoxBacks.addActionListener(this); - cbFourColour.addItemListener(this); - } - - private final JLabel lblVisualPreferences = new JLabel("Appearance"); - private final JSeparator separator_1 = new JSeparator(); - private final JPanel deckDesignPanel = new JPanel(); - private final ButtonGroup bgDeckDesign = new ButtonGroup(); - private final JLabel lblCardDesign = new JLabel("Card Design"); - private final JRadioButton rdbtnClassicDesign = new JRadioButton("Classic"); - private final JRadioButton rdbtnMinimalistDesign = new JRadioButton("Minimalist"); - private final JPanel deckPreviewPanel = new JPanel(); - private final JLabel labelJc = new JLabel(); - private final JLabel labelQd = new JLabel(); - private final JLabel labelKh = new JLabel(); - private final JLabel labelAs = new JLabel(); - private final JPanel jokerDesignPanel = new JPanel(); - private final ButtonGroup bgJokerDesign = new ButtonGroup(); - private final JRadioButton rdbtnClassicJokers = new JRadioButton("Classic"); - private final JRadioButton rdbtnDeveloperJokers = new JRadioButton("Developers"); - private final JLabel lblJokerDesign = new JLabel("Joker Design"); - private final JPanel jokerPreviewPanel = new JPanel(); - private final JLabel labelJo0 = new JLabel(); - private final JLabel labelJo1 = new JLabel(); - private final JLabel labelJo2 = new JLabel(); - private final JLabel labelJo3 = new JLabel(); - private final JCheckBox cbFourColour = new JCheckBox("Use 4 colour deck"); - private final JPanel backDesignPanel = new JPanel(); - private final JLabel lblCardBacks = new JLabel("Back Design"); - private final JComboBox> comboBoxBacks = new JComboBox<>(); - private final JComboBox comboBoxLookAndFeel = new JComboBox<>(); - private final JLabel labelBack = new JLabel(); - private final JLabel lblLookFeel = new JLabel("Look & Feel"); - private final JTextPane txtpnLookAndFeelDisclaimer = new JTextPane(); - private final JPanel panelLookAndFeel = new JPanel(); - - /** - * Abstract methods - */ - @Override - public void initVariables() - { - getVariablesFromPrefs(); - - selectRadioButtonsBasedOnDirectories(); - refreshDeckPreview(); - refreshJokerPreview(); - - selectCardBackBasedOnPreference(); - refreshCardBackPreview(); - setLookAndFeelComboBoxModel(); - - hideLockedFields(); - } - - @Override - public boolean valid() - { - return true; - } - - @Override - public void savePreferences() - { - preferenceStore.save(PreferenceSetting.DeckDesign, deckDesign); - preferenceStore.save(PreferenceSetting.JokerDesign, jokerDesign); - preferenceStore.save(PreferenceSetting.NumberOfColours, numberOfColours); - preferenceStore.save(PreferenceSetting.CardBacks, cardBacks); - preferenceStore.save(PreferenceSetting.LookAndFeel, (String)comboBoxLookAndFeel.getSelectedItem()); - - ScreenCache.get(MainScreen.class).fireAppearancePreferencesChange(); - } - - private void getVariablesFromPrefs() - { - deckDesign = getPreference(PreferenceSetting.DeckDesign); - jokerDesign = getPreference(PreferenceSetting.JokerDesign); - numberOfColours = getPreference(PreferenceSetting.NumberOfColours); - cardBacks = getPreference(PreferenceSetting.CardBacks); - lookAndFeel = getPreference(PreferenceSetting.LookAndFeel); - } - - private void hideLockedFields() - { - toggleLockedComponent(cbFourColour, Reward.FourColours); - toggleLockedComponent(rdbtnMinimalistDesign, Reward.MinimalistDeck); - toggleLockedComponent(rdbtnDeveloperJokers, Reward.DeveloperSet); - } - - private void refreshDeckPreview() - { - ImageIcon jackClubs = GameUtil.getImageForCard("Jc", deckDesign, jokerDesign, numberOfColours); - ImageIcon queenDiamonds = GameUtil.getImageForCard("Qd", deckDesign, jokerDesign, numberOfColours); - ImageIcon kingHearts = GameUtil.getImageForCard("Kh", deckDesign, jokerDesign, numberOfColours); - ImageIcon aceSpades = GameUtil.getImageForCard("As", deckDesign, jokerDesign, numberOfColours); - labelJc.setIcon(jackClubs); - labelQd.setIcon(queenDiamonds); - labelKh.setIcon(kingHearts); - labelAs.setIcon(aceSpades); - } - - private void refreshJokerPreview() - { - ImageIcon jo0 = GameUtil.getImageForCard("Jo0", deckDesign, jokerDesign, numberOfColours); - ImageIcon jo1 = GameUtil.getImageForCard("Jo1", deckDesign, jokerDesign, numberOfColours); - ImageIcon jo2 = GameUtil.getImageForCard("Jo2", deckDesign, jokerDesign, numberOfColours); - ImageIcon jo3 = GameUtil.getImageForCard("Jo3", deckDesign, jokerDesign, numberOfColours); - labelJo0.setIcon(jo0); - labelJo1.setIcon(jo1); - labelJo2.setIcon(jo2); - labelJo3.setIcon(jo3); - } - - private void selectCardBackBasedOnPreference() - { - Vector> backs = initialiseBacksVector(); - - ComboBoxModel> model = new DisabledComboBoxModel<>(backs); - comboBoxBacks.setModel(model); - - ComboBoxItem selectedItem = getSelectedItemForCode(backs, cardBacks); - if (selectedItem == null) - { - selectedItem = new ComboBoxItem<>("backBlue", "Blue"); - } - - comboBoxBacks.setSelectedItem(selectedItem); - } - - private Vector> initialiseBacksVector() - { - Vector> backs = new Vector<>(); - - backs.addElement(new ComboBoxItem<>("backBlue", "Blue")); - backs.addElement(new ComboBoxItem<>("backRed", "Red")); - - addIfUnlocked(backs, new ComboBoxItem<>("backGreen", "Green"), Reward.FourColours); - addIfUnlocked(backs, new ComboBoxItem<>("backPurple", "Purple"), Reward.NegativeJacks); - addIfUnlocked(backs, new ComboBoxItem<>("backOrange", "Orange"), Reward.Blind); - addIfUnlocked(backs, new ComboBoxItem<>("backLightBlue", "Light Blue"), Reward.MinimalistDeck); - addIfUnlocked(backs, new ComboBoxItem<>("backPink", "Pink"), Reward.Vectropy); - addIfUnlocked(backs, new ComboBoxItem<>("backSilver", "Silver"), Reward.CardReveal); - addIfUnlocked(backs, new ComboBoxItem<>("backGold", "Gold"), Reward.ExtraSuits); - addIfUnlocked(backs, new ComboBoxItem<>("backMatrix", "Matrix"), Reward.Illegal); - addIfUnlocked(backs, new ComboBoxItem<>("backCosmic", "Cosmic"), Reward.DeveloperSet); - addIfUnlocked(backs, new ComboBoxItem<>("backRainbow", "Rainbow"), Reward.Cheats); - - return backs; - } - private void addIfUnlocked(Vector> backs, ComboBoxItem item, - Reward reward) - { - if (reward.isUnlocked()) - { - backs.addElement(item); - } - else - { - ComboBoxItem disabledItem = new ComboBoxItem<>("", reward.getThreshold() + " achievements to unlock"); - disabledItem.setEnabled(false); - backs.addElement(disabledItem); - } - } - - private void setLookAndFeelComboBoxModel() - { - Vector backs = new Vector<>(); - for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) - { - String lookAndFeelName = info.getName(); - backs.add(lookAndFeelName); - } - - ComboBoxModel model = new DefaultComboBoxModel<>(backs); - comboBoxLookAndFeel.setModel(model); - comboBoxLookAndFeel.setSelectedItem(lookAndFeel); - } - - private ComboBoxItem getSelectedItemForCode(Vector> backs, String code) - { - int size = backs.size(); - for (int i=0; i back = backs.get(i); - String backCode = back.getHiddenData(); - - if (backCode.equals(code)) - { - return back; - } - } - - return null; - } - - @SuppressWarnings("unchecked") - private void refreshCardBackPreview() - { - ComboBoxItem selection = (ComboBoxItem)comboBoxBacks.getSelectedItem(); - if (selection == null) - { - cardBacks = comboBoxBacks.getItemAt(0).getHiddenData(); - } - else - { - cardBacks = selection.getHiddenData(); - } - - ImageIcon back = new ImageIcon(getClass().getResource("/backs/" + cardBacks + ".png")); - labelBack.setIcon(back); - } - - private void selectRadioButtonsBasedOnDirectories() - { - cbFourColour.setSelected(numberOfColours.equals(FOUR_COLOURS)); - - if (deckDesign.equals(DECK_DESIGN_CLASSIC)) - { - rdbtnClassicDesign.setSelected(true); - } - else if (deckDesign.equals(DECK_DESIGN_ALTERNATE)) - { - rdbtnMinimalistDesign.setSelected(true); - } - - if (jokerDesign.equals(JOKER_DESIGN_CLASSIC)) - { - rdbtnClassicJokers.setSelected(true); - } - else if (jokerDesign.equals(JOKER_DESIGN_DEVELOPERS)) - { - rdbtnDeveloperJokers.setSelected(true); - } - } - - @Override - public void actionPerformed(ActionEvent arg0) - { - Object source = arg0.getSource(); - if (source == rdbtnClassicDesign) - { - deckDesign = DECK_DESIGN_CLASSIC; - refreshDeckPreview(); - } - else if (source == rdbtnMinimalistDesign) - { - deckDesign = DECK_DESIGN_ALTERNATE; - refreshDeckPreview(); - } - else if (source == rdbtnClassicJokers) - { - jokerDesign = JOKER_DESIGN_CLASSIC; - refreshJokerPreview(); - } - else if (source == rdbtnDeveloperJokers) - { - jokerDesign = JOKER_DESIGN_DEVELOPERS; - refreshJokerPreview(); - } - else if (source == comboBoxBacks) - { - refreshCardBackPreview(); - } - } - - @Override - public void itemStateChanged(ItemEvent arg0) - { - boolean enabled = cbFourColour.isSelected(); - if (enabled) - { - numberOfColours = FOUR_COLOURS; - } - else - { - numberOfColours = TWO_COLOURS; - } - - refreshDeckPreview(); - refreshJokerPreview(); - } -} diff --git a/client/src/main/java/screen/PreferencesPanelGameplay.java b/client/src/main/java/screen/PreferencesPanelGameplay.java deleted file mode 100644 index e837bc5f..00000000 --- a/client/src/main/java/screen/PreferencesPanelGameplay.java +++ /dev/null @@ -1,338 +0,0 @@ -package screen; - -import java.awt.FlowLayout; -import java.awt.Font; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; - -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JSeparator; -import javax.swing.JSlider; -import javax.swing.JSpinner; -import javax.swing.SpinnerNumberModel; -import javax.swing.border.EmptyBorder; -import javax.swing.border.TitledBorder; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -import achievement.Reward; -import game.GameMode; -import preference.PreferenceSetting; -import util.Debug; -import util.Registry; - -import static preference.PreferenceSettingKt.getPreference; -import static util.ClientGlobals.preferenceStore; - -public class PreferencesPanelGameplay extends AbstractPreferencesPanel - implements ChangeListener, - ItemListener, - Registry -{ - private GameMode gameMode = GameMode.Entropy; - private boolean includeJokers = false; - private int numberOfCards = 5; - private int jokerQuantity = 2; - private int jokerValue = 2; - private boolean playBlind = false; - private boolean playWithHandicap = false; - private int handicapAmount = 1; - private boolean includeStars = false; - private boolean includeMoons = false; - private boolean negativeJacks = false; - private boolean cardReveal = false; - - public PreferencesPanelGameplay() - { - setLayout(null); - separatorTitle.setBounds(0, 38, 429, 2); - add(separatorTitle); - lblGameplay.setBounds(184, 12, 60, 17); - add(lblGameplay); - lblGameplay.setFont(new Font("Tahoma", Font.PLAIN, 14)); - lblWarning.setBounds(65, 395, 304, 14); - add(lblWarning); - lblWarning.setFont(new Font("Tahoma", Font.ITALIC, 11)); - panelGameMode.setBorder(new TitledBorder(null, "Mode", TitledBorder.LEADING, TitledBorder.TOP, null, null)); - panelGameMode.setBounds(20, 51, 165, 73); - add(panelGameMode); - panelGameMode.setLayout(new FlowLayout(FlowLayout.LEADING, 5, 10)); - panelGameMode.add(rdbtnEntropy); - rdbtnEntropy.setFont(new Font("Tahoma", Font.PLAIN, 11)); - bgMode.add(rdbtnEntropy); - panelGameMode.add(rdbtnVectropy); - rdbtnVectropy.setFont(new Font("Tahoma", Font.PLAIN, 11)); - bgMode.add(rdbtnVectropy); - panelDeck.setBorder(new TitledBorder(null, "Deck", TitledBorder.LEADING, TitledBorder.TOP, null, null)); - panelDeck.setBounds(20, 253, 393, 131); - add(panelDeck); - panelDeck.setLayout(new GridLayout(0, 1, 0, 0)); - FlowLayout fl_panelJokers = (FlowLayout) panelJokers.getLayout(); - fl_panelJokers.setAlignment(FlowLayout.LEFT); - panelJokers.setBorder(new EmptyBorder(0, -5, 0, 0)); - panelDeck.add(panelJokers); - panelJokers.add(cbJokers); - cbJokers.setFont(new Font("Tahoma", Font.PLAIN, 11)); - jokerQuantitySpinner.setFont(new Font("Tahoma", Font.PLAIN, 11)); - panelJokers.add(jokerQuantitySpinner); - lblWorth.setFont(new Font("Tahoma", Font.PLAIN, 11)); - panelJokers.add(lblWorth); - jokerValueSpinner.setFont(new Font("Tahoma", Font.PLAIN, 11)); - panelJokers.add(jokerValueSpinner); - cbJokers.addItemListener(this); - panelDeck.add(cbNegativeJacks); - cbNegativeJacks.setSelected(false); - cbNegativeJacks.setFont(new Font("Tahoma", Font.PLAIN, 11)); - panelDeck.add(cbIncludeMoons); - cbIncludeMoons.setFont(new Font("Tahoma", Font.PLAIN, 11)); - panelDeck.add(cbIncludeStars); - cbIncludeStars.setFont(new Font("Tahoma", Font.PLAIN, 11)); - panelGameplay.setBorder(new TitledBorder(null, "Gameplay", TitledBorder.LEADING, TitledBorder.TOP, null, null)); - panelGameplay.setBounds(20, 135, 393, 107); - add(panelGameplay); - panelGameplay.setLayout(new GridLayout(0, 1, 0, 0)); - handicapPanel.setBorder(new EmptyBorder(0, -5, 0, 0)); - FlowLayout flowLayout_1 = (FlowLayout) handicapPanel.getLayout(); - flowLayout_1.setAlignment(FlowLayout.LEADING); - panelGameplay.add(handicapPanel); - handicapPanel.add(cbHandicap); - cbHandicap.setFont(new Font("Tahoma", Font.PLAIN, 11)); - cbHandicap.setToolTipText("Start with fewer cards than your opponents."); - handicapAmountSpinner.setFont(new Font("Tahoma", Font.PLAIN, 11)); - handicapPanel.add(handicapAmountSpinner); - handicapAmountSpinner.setToolTipText("Start with this many cards less than your opponents."); - cbHandicap.addItemListener(this); - panelGameplay.add(cbPlayBlind); - cbPlayBlind.setFont(new Font("Tahoma", Font.PLAIN, 11)); - cbPlayBlind.setToolTipText("Your hand will be face-down each round until you choose to view it manually."); - cbPlayersRevealCards.setFont(new Font("Tahoma", Font.PLAIN, 11)); - panelGameplay.add(cbPlayersRevealCards); - panelStartingCards.setBorder(new TitledBorder(null, "Starting cards", TitledBorder.LEADING, TitledBorder.TOP, null, null)); - panelStartingCards.setBounds(195, 51, 218, 73); - add(panelStartingCards); - numberOfCardsSlider.setFont(new Font("Tahoma", Font.PLAIN, 11)); - panelStartingCards.add(numberOfCardsSlider); - numberOfCardsSlider.setMinorTickSpacing(1); - numberOfCardsSlider.setPaintTicks(true); - numberOfCardsSlider.setPaintLabels(true); - numberOfCardsSlider.setMajorTickSpacing(4); - numberOfCardsSlider.setToolTipText(""); - numberOfCardsSlider.setMinimum(1); - numberOfCardsSlider.setMaximum(5); - numberOfCardsSlider.addChangeListener(this); - handicapAmountSpinner.addChangeListener(this); - - rdbtnEntropy.addActionListener(this); - rdbtnVectropy.addActionListener(this); - } - - private final JLabel lblGameplay = new JLabel("Gameplay"); - private final JSeparator separatorTitle = new JSeparator(); - private final JPanel panelGameMode = new JPanel(); - private final ButtonGroup bgMode = new ButtonGroup(); - private final JRadioButton rdbtnEntropy = new JRadioButton("Entropy"); - private final JRadioButton rdbtnVectropy = new JRadioButton("Vectropy"); - private final JPanel panelStartingCards = new JPanel(); - private final JSlider numberOfCardsSlider = new JSlider(); - private final JPanel panelGameplay = new JPanel(); - private final JPanel handicapPanel = new JPanel(); - private final JCheckBox cbHandicap = new JCheckBox("Handicap:"); - private final JSpinner handicapAmountSpinner = new JSpinner(); - private final JCheckBox cbPlayBlind = new JCheckBox("Play Blind"); - private final JCheckBox cbPlayersRevealCards = new JCheckBox("Players reveal cards"); - private final JPanel panelDeck = new JPanel(); - private final JPanel panelJokers = new JPanel(); - private final JCheckBox cbJokers = new JCheckBox("Jokers"); - private final JSpinner jokerQuantitySpinner = new JSpinner(); - private final JLabel lblWorth = new JLabel("worth"); - private final JSpinner jokerValueSpinner = new JSpinner(); - private final JCheckBox cbNegativeJacks = new JCheckBox("Jacks worth -1"); - private final JCheckBox cbIncludeMoons = new JCheckBox("Include Moons"); - private final JCheckBox cbIncludeStars = new JCheckBox("Include Stars"); - private final JLabel lblWarning = new JLabel("Note: Changes will not take effect until you start a new game."); - - @Override - public void initVariables() - { - getVariablesFromPreferences(); - - cbJokers.setSelected(includeJokers); - cbNegativeJacks.setSelected(negativeJacks); - cbPlayersRevealCards.setSelected(cardReveal); - jokerQuantitySpinner.setModel(new SpinnerNumberModel(jokerQuantity, 1, 4, 1)); - jokerValueSpinner.setModel(new SpinnerNumberModel(jokerValue, 2, 4, 1)); - numberOfCardsSlider.setValue(numberOfCards); - jokerQuantitySpinner.setValue(jokerQuantity); - jokerValueSpinner.setValue(jokerValue); - cbPlayBlind.setSelected(playBlind); - cbHandicap.setSelected(playWithHandicap); - jokerQuantitySpinner.setEnabled(includeJokers); - lblWorth.setEnabled(includeJokers); - jokerValueSpinner.setEnabled(includeJokers); - handicapAmountSpinner.setEnabled(playWithHandicap); - - adjustHandicapSpinner(); - - cbIncludeStars.setSelected(includeStars); - cbIncludeMoons.setSelected(includeMoons); - - rdbtnEntropy.setSelected(gameMode == GameMode.Entropy); - rdbtnVectropy.setSelected(gameMode == GameMode.Vectropy); - - hideLockedFields(); - } - - @Override - public boolean valid() - { - return true; - } - - @Override - public void savePreferences() - { - numberOfCards = numberOfCardsSlider.getValue(); - negativeJacks = cbNegativeJacks.isSelected(); - cardReveal = cbPlayersRevealCards.isSelected(); - jokerQuantity = includeJokers ? (int) jokerQuantitySpinner.getValue() : 0; - jokerValue = (int) jokerValueSpinner.getValue(); - handicapAmount = (int) handicapAmountSpinner.getValue(); - playBlind = cbPlayBlind.isSelected(); - includeStars = cbIncludeStars.isSelected(); - includeMoons = cbIncludeMoons.isSelected(); - - prefs.putInt(SHARED_INT_NUMBER_OF_CARDS, numberOfCards); - prefs.putBoolean(SHARED_BOOLEAN_NEGATIVE_JACKS, negativeJacks); - prefs.putInt(SHARED_INT_JOKER_QUANTITY, jokerQuantity); - prefs.putInt(SHARED_INT_JOKER_VALUE, jokerValue); - - preferenceStore.save(PreferenceSetting.PlayWithHandicap, playWithHandicap); - preferenceStore.save(PreferenceSetting.HandicapAmount, handicapAmount); - preferenceStore.save(PreferenceSetting.PlayBlind, playBlind); - prefs.putBoolean(SHARED_BOOLEAN_INCLUDE_STARS, includeStars); - prefs.putBoolean(SHARED_BOOLEAN_INCLUDE_MOONS, includeMoons); - prefs.putBoolean(SHARED_BOOLEAN_CARD_REVEAL, cardReveal); - preferenceStore.save(PreferenceSetting.GameMode, gameMode.name()); - } - - private void getVariablesFromPreferences() - { - numberOfCards = prefs.getInt(SHARED_INT_NUMBER_OF_CARDS, 5); - jokerQuantity = prefs.getInt(SHARED_INT_JOKER_QUANTITY, 2); - includeJokers = jokerQuantity > 0; - jokerValue = prefs.getInt(SHARED_INT_JOKER_VALUE, 2); - playWithHandicap = getPreference(PreferenceSetting.PlayWithHandicap); - handicapAmount = getPreference(PreferenceSetting.HandicapAmount); - playBlind = getPreference(PreferenceSetting.PlayBlind); - includeStars = prefs.getBoolean(SHARED_BOOLEAN_INCLUDE_STARS, false); - includeMoons = prefs.getBoolean(SHARED_BOOLEAN_INCLUDE_MOONS, false); - negativeJacks = prefs.getBoolean(SHARED_BOOLEAN_NEGATIVE_JACKS, false); - cardReveal = prefs.getBoolean(SHARED_BOOLEAN_CARD_REVEAL, false); - gameMode = GameMode.valueOf(getPreference(PreferenceSetting.GameMode)); - } - - private void adjustHandicapSpinner() - { - if (numberOfCards == 1) - { - cbHandicap.setSelected(false); - cbHandicap.setEnabled(false); - handicapAmountSpinner.setEnabled(false); - } - else - { - cbHandicap.setEnabled(true); - handicapAmountSpinner.setEnabled(cbHandicap.isSelected()); - - int newMax = numberOfCards - 1; - if (handicapAmount > newMax) - { - handicapAmount = newMax; - } - - handicapAmountSpinner.setModel(new SpinnerNumberModel(handicapAmount, 1, newMax, 1)); - } - } - - private void hideLockedFields() - { - toggleLockedComponent(cbNegativeJacks, Reward.NegativeJacks); - toggleLockedComponent(cbPlayBlind, Reward.Blind); - toggleLockedComponent(rdbtnVectropy, Reward.Vectropy); - toggleLockedComponent(cbPlayersRevealCards, Reward.CardReveal); - toggleLockedComponent(cbIncludeMoons, Reward.ExtraSuits); - toggleLockedComponent(cbIncludeStars, Reward.ExtraSuits); - } - - @Override - public void actionPerformed(ActionEvent arg0) - { - GameMode originalGameMode = gameMode; - - Object source = arg0.getSource(); - if (source == rdbtnEntropy) - { - gameMode = GameMode.Entropy; - } - else if (source == rdbtnVectropy) - { - gameMode = GameMode.Vectropy; - } - - if (originalGameMode != gameMode) - { - parent.gameModeChanged(gameMode); - } - } - - @Override - public void stateChanged(ChangeEvent arg0) - { - Object source = arg0.getSource(); - if (source == numberOfCardsSlider) - { - if (!numberOfCardsSlider.getValueIsAdjusting()) - { - numberOfCards = numberOfCardsSlider.getValue(); - adjustHandicapSpinner(); - } - } - else if (source == handicapAmountSpinner) - { - handicapAmount = (int)handicapAmountSpinner.getValue(); - } - else - { - Debug.stackTrace("Unexpected stateChanged: [" + source + "]"); - } - - } - - @Override - public void itemStateChanged(ItemEvent arg0) - { - Object source = arg0.getSource(); - if (source == cbJokers) - { - includeJokers = cbJokers.isSelected(); - lblWorth.setEnabled(includeJokers); - jokerQuantitySpinner.setEnabled(includeJokers); - jokerValueSpinner.setEnabled(includeJokers); - } - else if (source == cbHandicap) - { - playWithHandicap = cbHandicap.isSelected(); - handicapAmountSpinner.setEnabled(playWithHandicap); - } - else - { - Debug.stackTrace("Unexpected itemStateChanged: [" + source + "]"); - } - } -} \ No newline at end of file diff --git a/client/src/main/java/screen/PreferencesPanelMisc.java b/client/src/main/java/screen/PreferencesPanelMisc.java deleted file mode 100644 index 5337a036..00000000 --- a/client/src/main/java/screen/PreferencesPanelMisc.java +++ /dev/null @@ -1,305 +0,0 @@ -package screen; - -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.io.File; - -import javax.swing.ButtonGroup; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JRadioButton; -import javax.swing.JSeparator; -import javax.swing.JSpinner; -import javax.swing.JTextField; -import javax.swing.SpinnerNumberModel; -import javax.swing.SwingConstants; - -import preference.PreferenceSetting; -import util.*; - -import static preference.PreferenceSettingKt.*; -import static util.ClientGlobals.preferenceStore; - -public class PreferencesPanelMisc extends AbstractPreferencesPanel - implements ItemListener -{ - private boolean autosave = false; - private int gameSpeed = GAME_SPEED_MEDIUM; - private boolean saveReplays = false; - private String replayDirectory = ""; - private boolean openReplayOnFirstRound = false; - private boolean autoStartNextRound = false; - private int autoStartSeconds = 2; //2 seconds - private boolean popUpRoomsOnline = true; - private boolean checkForUpdates = true; - - public PreferencesPanelMisc() - { - setLayout(null); - - bgReplayRound.add(rdbtnFirstRound); - bgReplayRound.add(rdbtnLastRound); - bgSpeed.add(rdbtnSlow); - bgSpeed.add(rdbtnMedium); - bgSpeed.add(rdbtnFast); - chckbxSaveReplays.setFont(new Font("Tahoma", Font.PLAIN, 11)); - chckbxSaveReplays.setBounds(20, 67, 91, 22); - add(chckbxSaveReplays); - lblOtherOptions.setFont(new Font("Tahoma", Font.PLAIN, 14)); - lblOtherOptions.setBounds(171, 12, 86, 17); - add(lblOtherOptions); - separator_3.setBounds(0, 38, 429, 2); - add(separator_3); - chosenDirectory.setBounds(116, 67, 180, 22); - chosenDirectory.setEditable(false); - add(chosenDirectory); - chosenDirectory.setColumns(10); - btnSelectDirectory.setBounds(296, 67, 20, 22); - add(btnSelectDirectory); - chckbxAutosave.setBounds(20, 180, 127, 22); - add(chckbxAutosave); - chckbxAutosave.setFont(new Font("Tahoma", Font.PLAIN, 11)); - lblReplayViewerDefaults.setFont(new Font("Tahoma", Font.PLAIN, 11)); - lblReplayViewerDefaults.setBounds(20, 112, 127, 14); - add(lblReplayViewerDefaults); - rdbtnFirstRound.setFont(new Font("Tahoma", Font.PLAIN, 11)); - rdbtnFirstRound.setBounds(144, 109, 91, 20); - add(rdbtnFirstRound); - rdbtnLastRound.setFont(new Font("Tahoma", Font.PLAIN, 11)); - rdbtnLastRound.setBounds(237, 109, 91, 20); - add(rdbtnLastRound); - lblGameSpeed.setBounds(20, 148, 86, 14); - add(lblGameSpeed); - lblGameSpeed.setHorizontalAlignment(SwingConstants.LEFT); - lblGameSpeed.setFont(new Font("Tahoma", Font.PLAIN, 11)); - rdbtnSlow.setBounds(144, 144, 60, 20); - add(rdbtnSlow); - rdbtnSlow.setFont(new Font("Tahoma", Font.PLAIN, 11)); - rdbtnMedium.setBounds(206, 144, 70, 20); - add(rdbtnMedium); - rdbtnMedium.setFont(new Font("Tahoma", Font.PLAIN, 11)); - rdbtnFast.setBounds(274, 144, 54, 20); - add(rdbtnFast); - rdbtnFast.setFont(new Font("Tahoma", Font.PLAIN, 11)); - chckbxAutoStartNextRound.setFont(new Font("Tahoma", Font.PLAIN, 11)); - chckbxAutoStartNextRound.setBounds(20, 205, 208, 23); - add(chckbxAutoStartNextRound); - chckbxPopUpRooms.setFont(new Font("Tahoma", Font.PLAIN, 11)); - chckbxPopUpRooms.setBounds(20, 230, 208, 23); - add(chckbxPopUpRooms); - spinnerAutoStartSeconds.setBounds(228, 205, 38, 22); - add(spinnerAutoStartSeconds); - lblSeconds.setFont(new Font("Tahoma", Font.PLAIN, 11)); - lblSeconds.setBounds(275, 206, 55, 20); - add(lblSeconds); - chckbxCheckForUpdates.setFont(new Font("Tahoma", Font.PLAIN, 11)); - chckbxCheckForUpdates.setBounds(20, 256, 237, 23); - add(chckbxCheckForUpdates); - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - - rdbtnFast.addActionListener(this); - rdbtnMedium.addActionListener(this); - rdbtnSlow.addActionListener(this); - btnSelectDirectory.addActionListener(this); - chckbxSaveReplays.addItemListener(this); - chckbxAutoStartNextRound.addItemListener(this); - } - - private final JLabel lblOtherOptions = new JLabel("Other Options"); - private final JSeparator separator_3 = new JSeparator(); - private final JFileChooser fc = new JFileChooser(); - private final JTextField chosenDirectory = new JTextField(); - private final JCheckBox chckbxSaveReplays = new JCheckBox("Save replays"); - private final JButton btnSelectDirectory = new JButton("..."); - private final JCheckBox chckbxAutosave = new JCheckBox("Autosave on exit"); - private final ButtonGroup bgSpeed = new ButtonGroup(); - private final JRadioButton rdbtnSlow = new JRadioButton("Slow"); - private final JRadioButton rdbtnMedium = new JRadioButton("Medium"); - private final JRadioButton rdbtnFast = new JRadioButton("Fast"); - private final JLabel lblGameSpeed = new JLabel("Game speed"); - private final JCheckBox chckbxAutoStartNextRound = new JCheckBox("Automatically start next round after"); - private final JCheckBox chckbxPopUpRooms = new JCheckBox("Pop up online rooms on my turn"); - private final JSpinner spinnerAutoStartSeconds = new JSpinner(); - private final JLabel lblSeconds = new JLabel("seconds"); - private final JLabel lblReplayViewerDefaults = new JLabel("Replay viewer default"); - private final ButtonGroup bgReplayRound = new ButtonGroup(); - private final JRadioButton rdbtnFirstRound = new JRadioButton("First Round"); - private final JRadioButton rdbtnLastRound = new JRadioButton("Last Round"); - private final JCheckBox chckbxCheckForUpdates = new JCheckBox("Automatically check for updates"); - - /** - * Abstract methods - */ - @Override - public void initVariables() - { - getVariablesFromPrefs(); - - spinnerAutoStartSeconds.setModel(new SpinnerNumberModel(autoStartSeconds, 1, 5, 1)); - chosenDirectory.setText(replayDirectory + "\\Replays"); - chckbxAutosave.setSelected(autosave); - rdbtnSlow.setSelected(gameSpeed == GAME_SPEED_SLOW); - rdbtnMedium.setSelected(gameSpeed == GAME_SPEED_MEDIUM); - rdbtnFast.setSelected(gameSpeed == GAME_SPEED_FAST); - chckbxSaveReplays.setSelected(saveReplays); - chosenDirectory.setText(replayDirectory + "\\Replays"); - chosenDirectory.setEnabled(saveReplays); - btnSelectDirectory.setEnabled(saveReplays); - chckbxAutoStartNextRound.setSelected(autoStartNextRound); - chckbxPopUpRooms.setSelected(popUpRoomsOnline); - chckbxCheckForUpdates.setSelected(checkForUpdates); - spinnerAutoStartSeconds.setEnabled(autoStartNextRound); - lblSeconds.setEnabled(autoStartNextRound); - spinnerAutoStartSeconds.setValue(autoStartSeconds); - rdbtnFirstRound.setSelected(openReplayOnFirstRound); - rdbtnLastRound.setSelected(!openReplayOnFirstRound); - } - - @Override - public boolean valid() - { - return confirmChangeOfDirectory(); - } - - @Override - public void savePreferences() - { - autosave = chckbxAutosave.isSelected(); - openReplayOnFirstRound = rdbtnFirstRound.isSelected(); - autoStartSeconds = (int)spinnerAutoStartSeconds.getValue(); - popUpRoomsOnline = chckbxPopUpRooms.isSelected(); - checkForUpdates = chckbxCheckForUpdates.isSelected(); - - preferenceStore.save(PreferenceSetting.SaveReplays, saveReplays); - preferenceStore.save(PreferenceSetting.AutoSave, autosave); - preferenceStore.save(PreferenceSetting.ReplayDirectory, replayDirectory); - preferenceStore.save(PreferenceSetting.OpenReplayOnFirstRound, openReplayOnFirstRound); - preferenceStore.save(PreferenceSetting.AutoStartNextRound, autoStartNextRound); - preferenceStore.save(PreferenceSetting.AutoStartSeconds, autoStartSeconds); - preferenceStore.save(PreferenceSetting.PopUpRooms, popUpRoomsOnline); - preferenceStore.save(PreferenceSetting.CheckForUpdates, checkForUpdates); - preferenceStore.save(PreferenceSetting.GameSpeed, gameSpeed); - } - - private void getVariablesFromPrefs() - { - autosave = getPreference(PreferenceSetting.AutoSave); - gameSpeed = getPreference(PreferenceSetting.GameSpeed); - saveReplays = getPreference(PreferenceSetting.SaveReplays); - replayDirectory = getPreference(PreferenceSetting.ReplayDirectory); - openReplayOnFirstRound = getPreference(PreferenceSetting.OpenReplayOnFirstRound); - autoStartNextRound = getPreference(PreferenceSetting.AutoStartNextRound); - autoStartSeconds = getPreference(PreferenceSetting.AutoStartSeconds); - popUpRoomsOnline = getPreference(PreferenceSetting.PopUpRooms); - checkForUpdates = getPreference(PreferenceSetting.CheckForUpdates); - } - - private boolean confirmChangeOfDirectory() - { - String originalReplayDirectory = preferenceStore.get(PreferenceSetting.ReplayDirectory); - - File[] myExistingFiles = new File(originalReplayDirectory + "//Replays//" + ReplayFileUtil.FOLDER_PERSONAL_REPLAYS).listFiles(); - int myExistingFilesLength = 0; - if (myExistingFiles != null) - { - myExistingFilesLength = myExistingFiles.length; - } - - File[] importedExistingFiles = new File(originalReplayDirectory + "//Replays//"+ ReplayFileUtil.FOLDER_IMPORTED_REPLAYS).listFiles(); - int importedExistingFilesLength = 0; - if (importedExistingFiles != null) - { - importedExistingFilesLength = importedExistingFiles.length; - } - - if (!replayDirectory.equals(originalReplayDirectory) && (myExistingFilesLength != 0 || importedExistingFilesLength != 0)) - { - int choice = DialogUtil.showQuestion("You have changed your replay directory but there are still files in the old one. " - + "\nWould you like to move these files to the new location?", true); - - if (choice == JOptionPane.YES_OPTION) - { - ReplayFileUtil.moveReplays(myExistingFiles, importedExistingFiles, originalReplayDirectory, replayDirectory); - } - else if (choice == JOptionPane.CANCEL_OPTION) - { - return false; - } - else - { - DialogUtil.showInfo("Existing replay files were left in the old directory and will have to be deleted or moved manually."); - } - } - - return true; - } - - private void selectReplayDirectory() - { - try - { - int returnVal = fc.showOpenDialog(this); - if (returnVal == JFileChooser.APPROVE_OPTION) - { - File file = fc.getSelectedFile(); - - replayDirectory = file.getPath(); - chosenDirectory.setText(replayDirectory + "\\Replays"); - Debug.append("Selected " + file.getPath() + " as replay directory.", true); - } - else - { - Debug.append("Directory selection cancelled by user.", true); - } - } - catch (Throwable t) - { - Debug.stackTrace(t); - } - } - - @Override - public void actionPerformed(ActionEvent arg0) - { - Object source = arg0.getSource(); - if (source == rdbtnFast) - { - gameSpeed = GAME_SPEED_FAST; - } - else if (source == rdbtnMedium) - { - gameSpeed = GAME_SPEED_MEDIUM; - } - else if (source == rdbtnSlow) - { - gameSpeed = GAME_SPEED_SLOW; - } - else if (source == btnSelectDirectory) - { - selectReplayDirectory(); - } - } - - @Override - public void itemStateChanged(ItemEvent arg0) - { - Object source = arg0.getSource(); - if (source == chckbxSaveReplays) - { - saveReplays = chckbxSaveReplays.isSelected(); - chosenDirectory.setEnabled(saveReplays); - btnSelectDirectory.setEnabled(saveReplays); - } - else if (source == chckbxAutoStartNextRound) - { - autoStartNextRound = chckbxAutoStartNextRound.isSelected(); - lblSeconds.setEnabled(autoStartNextRound); - spinnerAutoStartSeconds.setEnabled(autoStartNextRound); - } - } -} \ No newline at end of file diff --git a/client/src/main/java/screen/PreferencesPanelPlayers.java b/client/src/main/java/screen/PreferencesPanelPlayers.java deleted file mode 100644 index be838b2d..00000000 --- a/client/src/main/java/screen/PreferencesPanelPlayers.java +++ /dev/null @@ -1,468 +0,0 @@ -package screen; - -import java.awt.Font; -import java.awt.Point; -import java.awt.event.ActionEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.ArrayList; -import java.util.Vector; - -import javax.swing.ComboBoxModel; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPopupMenu; -import javax.swing.JScrollPane; -import javax.swing.JSeparator; -import javax.swing.JTable; -import javax.swing.JTextField; -import javax.swing.ListSelectionModel; -import javax.swing.SwingConstants; -import javax.swing.SwingUtilities; -import javax.swing.table.TableModel; -import javax.swing.table.TableRowSorter; - -import game.GameMode; -import object.ApiStrategy; -import object.LimitedDocument; -import preference.PreferenceSetting; -import util.ApiUtil; -import util.CpuStrategies; -import util.Debug; -import util.DialogUtil; -import util.TableUtil; -import util.TableUtil.DefaultModel; - -import static preference.PreferenceSettingKt.getPreference; -import static util.ClientGlobals.preferenceStore; - -public class PreferencesPanelPlayers extends AbstractPreferencesPanel - implements MouseListener, - ItemListener -{ - private String playerName = "Player"; - private String opponentOneName = "Mark"; - private String opponentTwoName = "Dave"; - private String opponentThreeName = "Tom"; - private boolean opponentTwoEnabled = false; - private boolean opponentThreeEnabled = false; - private String opponentOneStrategy = "Mark"; - private String opponentTwoStrategy = "Basic"; - private String opponentThreeStrategy = "Basic"; - private ArrayList apiStrategies = null; - private GameMode gameMode = GameMode.Entropy; - - public PreferencesPanelPlayers() - { - setLayout(null); - - separator_2.setBounds(0, 38, 434, 2); - add(separator_2); - lblPlayers.setBounds(172, 12, 70, 17); - add(lblPlayers); - lblPlayers.setHorizontalAlignment(SwingConstants.CENTER); - lblPlayers.setFont(new Font("Tahoma", Font.PLAIN, 14)); - playerNameField.setDocument(new LimitedDocument(10)); - opponentOneNameField.setDocument(new LimitedDocument(10)); - opponentTwoNameField.setDocument(new LimitedDocument(10)); - opponentThreeNameField.setDocument(new LimitedDocument(10)); - opponentOneNameField.setBounds(60, 102, 86, 22); - add(opponentOneNameField); - opponentOneNameField.setText(opponentOneName); - opponentOneNameField.setColumns(10); - cbOpponentTwo.setBounds(22, 143, 29, 23); - add(cbOpponentTwo); - cbOpponentThree.setBounds(22, 185, 29, 23); - add(cbOpponentThree); - opponentTwoNameField.setBounds(60, 144, 86, 22); - add(opponentTwoNameField); - opponentTwoNameField.setText(opponentTwoName); - opponentTwoNameField.setColumns(10); - opponentThreeNameField.setBounds(60, 186, 86, 22); - add(opponentThreeNameField); - opponentThreeNameField.setText(opponentThreeName); - opponentThreeNameField.setColumns(10); - opponentTwoStrat.setBounds(172, 144, 197, 22); - add(opponentTwoStrat); - opponentThreeStrat.setBounds(172, 186, 197, 22); - add(opponentThreeStrat); - opponentOneStrat.setBounds(172, 102, 197, 22); - add(opponentOneStrat); - playerNameField.setBounds(212, 60, 86, 22); - add(playerNameField); - playerNameField.setColumns(10); - lblPlayerName.setBounds(122, 60, 80, 22); - add(lblPlayerName); - label.setFont(new Font("Tahoma", Font.ITALIC, 11)); - label.setBounds(65, 395, 304, 14); - add(label); - lblApiHeader.setHorizontalAlignment(SwingConstants.CENTER); - lblApiHeader.setFont(new Font("Tahoma", Font.PLAIN, 14)); - lblApiHeader.setBounds(171, 240, 86, 17); - add(lblApiHeader); - separator_4.setBounds(0, 265, 429, 2); - add(separator_4); - scrollPane.setBounds(17, 307, 402, 80); - add(scrollPane); - tableApiStrategies.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - scrollPane.setViewportView(tableApiStrategies); - btnNewApiStrategy.setBounds(17, 278, 151, 23); - add(btnNewApiStrategy); - tableApiStrategies.getTableHeader().setReorderingAllowed(false); - popupMenu.add(enableItem); - popupMenu.add(amendItem); - popupMenu.add(deleteItem); - - btnNewApiStrategy.addActionListener(this); - enableItem.addActionListener(this); - deleteItem.addActionListener(this); - amendItem.addActionListener(this); - tableApiStrategies.addMouseListener(this); - cbOpponentTwo.addItemListener(this); - cbOpponentThree.addItemListener(this); - } - - private final JLabel lblPlayers = new JLabel("Players"); - private final JSeparator separator_2 = new JSeparator(); - private final JLabel lblPlayerName = new JLabel("Player Name"); - private final JTextField playerNameField = new JTextField(); - private final JTextField opponentOneNameField = new JTextField(); - private final JTextField opponentTwoNameField = new JTextField(); - private final JTextField opponentThreeNameField = new JTextField(); - private final JCheckBox cbOpponentTwo = new JCheckBox(); - private final JCheckBox cbOpponentThree = new JCheckBox(); - private final JComboBox opponentOneStrat = new JComboBox<>(); - private final JComboBox opponentTwoStrat = new JComboBox<>(); - private final JComboBox opponentThreeStrat = new JComboBox<>(); - private final JLabel label = new JLabel("Note: Changes will not take effect until you start a new game."); - private final JSeparator separator_4 = new JSeparator(); - private final JLabel lblApiHeader = new JLabel("API Options"); - private final JScrollPane scrollPane = new JScrollPane(); - private final JTable tableApiStrategies = new JTable(); - private final JPopupMenu popupMenu = new JPopupMenu(); - private final JMenuItem amendItem = new JMenuItem("Amend"); - private final JMenuItem deleteItem = new JMenuItem("Delete"); - private final JMenuItem enableItem = new JMenuItem("Enable"); - private final JButton btnNewApiStrategy = new JButton("New API Strategy"); - - /** - * Abstract methods - */ - @Override - public void initVariables() - { - getVariablesFromPrefs(); - buildApiTable(); - setPlayerNames(); - setOpponentEnablementAndStrategies(); - setOpponentStrategies(); - } - - @Override - public boolean valid() - { - String nameOne = playerNameField.getText(); - String nameTwo = opponentOneNameField.getText(); - String nameThree = opponentTwoNameField.getText(); - String nameFour = opponentThreeNameField.getText(); - - if (nameOne.length() == 0 - || nameTwo.length() == 0 - || nameThree.length() == 0 - || nameFour.length() == 0) - { - DialogUtil.showError("You must enter a name for each player."); - return false; - } - - return true; - } - - @Override - public void savePreferences() - { - playerName = playerNameField.getText(); - opponentOneName = opponentOneNameField.getText(); - opponentTwoName = opponentTwoNameField.getText(); - opponentThreeName = opponentThreeNameField.getText(); - opponentOneStrategy = (String) opponentOneStrat.getSelectedItem(); - opponentTwoStrategy = (String) opponentTwoStrat.getSelectedItem(); - opponentThreeStrategy = (String) opponentThreeStrat.getSelectedItem(); - - preferenceStore.save(PreferenceSetting.PlayerName, playerName); - preferenceStore.save(PreferenceSetting.OpponentOneName, opponentOneName); - preferenceStore.save(PreferenceSetting.OpponentTwoName, opponentTwoName); - preferenceStore.save(PreferenceSetting.OpponentThreeName, opponentThreeName); - preferenceStore.save(PreferenceSetting.OpponentTwoEnabled, opponentTwoEnabled); - preferenceStore.save(PreferenceSetting.OpponentThreeEnabled, opponentThreeEnabled); - preferenceStore.save(PreferenceSetting.OpponentOneStrategy, opponentOneStrategy); - preferenceStore.save(PreferenceSetting.OpponentTwoStrategy, opponentTwoStrategy); - preferenceStore.save(PreferenceSetting.OpponentThreeStrategy, opponentThreeStrategy); - - ApiUtil.saveApiStrategiesToPreferences(apiStrategies); - } - - - private void getVariablesFromPrefs() - { - playerName = getPreference(PreferenceSetting.PlayerName); - opponentOneName = getPreference(PreferenceSetting.OpponentOneName); - opponentTwoName = getPreference(PreferenceSetting.OpponentTwoName); - opponentThreeName = getPreference(PreferenceSetting.OpponentThreeName); - opponentTwoEnabled = getPreference(PreferenceSetting.OpponentTwoEnabled); - opponentThreeEnabled = getPreference(PreferenceSetting.OpponentThreeEnabled); - opponentOneStrategy = getPreference(PreferenceSetting.OpponentOneStrategy); - opponentTwoStrategy = getPreference(PreferenceSetting.OpponentTwoStrategy); - opponentThreeStrategy = getPreference(PreferenceSetting.OpponentThreeStrategy); - apiStrategies = ApiUtil.getApiStrategiesFromPreferences(); - - gameMode = GameMode.valueOf(getPreference(PreferenceSetting.GameMode)); - } - - private void setPlayerNames() - { - playerNameField.setText(playerName); - opponentOneNameField.setText(opponentOneName); - opponentTwoNameField.setText(opponentTwoName); - opponentThreeNameField.setText(opponentThreeName); - } - - private void setOpponentEnablementAndStrategies() - { - cbOpponentThree.setEnabled(opponentTwoEnabled); - cbOpponentTwo.setEnabled(!opponentThreeEnabled); - - cbOpponentTwo.setSelected(opponentTwoEnabled); - cbOpponentThree.setSelected(opponentThreeEnabled); - opponentTwoNameField.setEnabled(opponentTwoEnabled); - opponentThreeNameField.setEnabled(opponentThreeEnabled); - opponentTwoStrat.setEnabled(opponentTwoEnabled); - opponentThreeStrat.setEnabled(opponentThreeEnabled); - } - - private void setOpponentStrategies() - { - opponentOneStrat.setSelectedItem(opponentOneStrategy); - opponentTwoStrat.setSelectedItem(opponentTwoStrategy); - opponentThreeStrat.setSelectedItem(opponentThreeStrategy); - } - - private void buildApiTable() - { - DefaultModel model = new TableUtil.DefaultModel(); - tableApiStrategies.setModel(model); - - //Columns - model.addColumn("Name"); - model.addColumn("Port"); - model.addColumn("Game"); - model.addColumn("Messaging"); - model.addColumn("Enabled"); - - //Centre rendering for everything but the last column - for (int i=0; i sorter = new TableRowSorter<>(model); - tableApiStrategies.setRowSorter(sorter); - - //Populate the rows - for (int i=0; i allStrategies = CpuStrategies.getAllStrategies(gameMode == GameMode.Entropy, apiStrategies); - - ComboBoxModel comboModel = new DefaultComboBoxModel<>(allStrategies); - opponentOneStrat.setModel(comboModel); - comboModel = new DefaultComboBoxModel<>(allStrategies); - opponentTwoStrat.setModel(comboModel); - comboModel = new DefaultComboBoxModel<>(allStrategies); - opponentThreeStrat.setModel(comboModel); - } - - private void enableApi(ApiStrategy strategy) - { - String question = "Strategy " + strategy.getName() + " was disabled due to the following error:" - + "\n\n" + strategy.getError() - + "\n\nWould you like to re-enable it?"; - - int option = DialogUtil.showQuestion(question, false); - if (option == JOptionPane.YES_OPTION) - { - strategy.setError(""); - buildApiTable(); - } - } - - private void amendApi(ApiStrategy strategy) - { - ApiAmendDialog.amendStrategy(strategy); - buildApiTable(); - } - - private void deleteApi(ApiStrategy strategy) - { - String question = "Are you sure you want to delete the " + strategy.getName() + " strategy?"; - int option = DialogUtil.showQuestion(question, false); - if (option == JOptionPane.YES_OPTION) - { - apiStrategies.remove(strategy); - buildApiTable(); - } - } - - private ApiStrategy getSelectedStrategyFromTable() - { - int row = tableApiStrategies.getSelectedRow(); - if (row == -1) - { - return null; - } - - int internalRow = tableApiStrategies.convertRowIndexToModel(row); - DefaultModel model = (DefaultModel)tableApiStrategies.getModel(); - String name = (String)model.getValueAt(internalRow, 0); - - int size = apiStrategies.size(); - for (int i=0; i strategies) + public static void saveApiStrategiesToPreferences(List strategies) { //Construct a document with any old root element Document apiDoc = XmlUtil.factoryNewDocument(); diff --git a/client/src/main/java/util/CpuStrategies.java b/client/src/main/java/util/CpuStrategies.java index 54213ef0..ae030c4f 100644 --- a/client/src/main/java/util/CpuStrategies.java +++ b/client/src/main/java/util/CpuStrategies.java @@ -15,7 +15,7 @@ public class CpuStrategies public static final String STRATEGY_BASIC = "Easy"; public static final String STRATEGY_EV = "Hard"; - public static Vector getAllStrategies(boolean entropy, ArrayList apiStrategies) + public static Vector getAllStrategies(boolean entropy, List apiStrategies) { Vector allStrategies = getFixedStrategies(entropy); @@ -30,7 +30,7 @@ public static Vector getAllStrategies(boolean entropy, ArrayList allStrategies, - ArrayList apiStrategies, boolean entropy) + List apiStrategies, boolean entropy) { int size = apiStrategies.size(); for (int i=0; i - panel.setParent(this) - panel.initVariables() - } + childPanels().forEach { panel -> panel.initVariables() } } private fun valid(): Boolean { @@ -58,15 +50,17 @@ class PreferencesDialog : SimpleDialog() { return true } - fun gameModeChanged(gameMode: GameMode?) { + fun gameModeChanged(gameMode: GameMode) { playersPanel.updateStrategySelection(gameMode) } private fun childPanels() = getAllChildComponentsForType() override fun okPressed() { - childPanels().forEach { it.savePreferences() } - closeDialog() + if (valid()) { + childPanels().forEach { it.savePreferences() } + closeDialog() + } } override fun cancelPressed() { diff --git a/client/src/main/kotlin/screen/preference/PreferencesPanelAppearance.kt b/client/src/main/kotlin/screen/preference/PreferencesPanelAppearance.kt new file mode 100644 index 00000000..887f7ee5 --- /dev/null +++ b/client/src/main/kotlin/screen/preference/PreferencesPanelAppearance.kt @@ -0,0 +1,397 @@ +package screen.preference + +import achievement.Reward +import bean.ComboBoxItem +import java.awt.Color +import java.awt.Dimension +import java.awt.Font +import java.awt.event.ActionEvent +import java.awt.event.ItemEvent +import java.awt.event.ItemListener +import java.util.Vector +import javax.swing.BorderFactory +import javax.swing.ButtonGroup +import javax.swing.ComboBoxModel +import javax.swing.DefaultComboBoxModel +import javax.swing.ImageIcon +import javax.swing.JCheckBox +import javax.swing.JComboBox +import javax.swing.JLabel +import javax.swing.JPanel +import javax.swing.JRadioButton +import javax.swing.JSeparator +import javax.swing.JTextPane +import javax.swing.SwingConstants +import javax.swing.UIManager +import javax.swing.border.LineBorder +import javax.swing.text.DefaultCaret +import `object`.DisabledComboBoxModel +import preference.DECK_DESIGN_ALTERNATE +import preference.DECK_DESIGN_CLASSIC +import preference.FOUR_COLOURS +import preference.JOKER_DESIGN_CLASSIC +import preference.JOKER_DESIGN_DEVELOPERS +import preference.PreferenceSetting +import preference.TWO_COLOURS +import preference.getPreference +import screen.MainScreen +import screen.ScreenCache +import util.ClientGlobals.preferenceStore +import util.GameUtil + +class PreferencesPanelAppearance(parent: PreferencesDialog) : + AbstractPreferencesPanel(parent), ItemListener { + private var deckDesign = "" + private var jokerDesign = "" + private var cardBacks = "" + private var numberOfColours = "" + private var lookAndFeel = "" + + private val lblVisualPreferences = JLabel("Appearance") + private val separator_1 = JSeparator() + private val deckDesignPanel = JPanel() + private val bgDeckDesign = ButtonGroup() + private val lblCardDesign = JLabel("Card Design") + private val rdbtnClassicDesign = JRadioButton("Classic") + private val rdbtnMinimalistDesign = JRadioButton("Minimalist") + private val deckPreviewPanel = JPanel() + private val labelJc = JLabel() + private val labelQd = JLabel() + private val labelKh = JLabel() + private val labelAs = JLabel() + private val jokerDesignPanel = JPanel() + private val bgJokerDesign = ButtonGroup() + private val rdbtnClassicJokers = JRadioButton("Classic") + private val rdbtnDeveloperJokers = JRadioButton("Developers") + private val lblJokerDesign = JLabel("Joker Design") + private val jokerPreviewPanel = JPanel() + private val labelJo0 = JLabel() + private val labelJo1 = JLabel() + private val labelJo2 = JLabel() + private val labelJo3 = JLabel() + private val cbFourColour = JCheckBox("Use 4 colour deck") + private val backDesignPanel = JPanel() + private val lblCardBacks = JLabel("Back Design") + private val comboBoxBacks = JComboBox>() + private val comboBoxLookAndFeel = JComboBox() + private val labelBack = JLabel() + private val lblLookFeel = JLabel("Look & Feel") + private val txtpnLookAndFeelDisclaimer = JTextPane() + private val panelLookAndFeel = JPanel() + + init { + preferredSize = Dimension(400, 760) + setLayout(null) + + bgDeckDesign.add(rdbtnClassicDesign) + bgDeckDesign.add(rdbtnMinimalistDesign) + bgJokerDesign.add(rdbtnClassicJokers) + bgJokerDesign.add(rdbtnDeveloperJokers) + deckDesignPanel.setBounds(17, 80, 374, 58) + add(deckDesignPanel) + deckDesignPanel.setBorder(LineBorder(Color.GRAY)) + deckDesignPanel.setLayout(null) + rdbtnClassicDesign.setBounds(6, 30, 72, 23) + deckDesignPanel.add(rdbtnClassicDesign) + rdbtnMinimalistDesign.setBounds(80, 30, 146, 23) + deckDesignPanel.add(rdbtnMinimalistDesign) + deckDesignPanel.add(lblCardDesign) + deckPreviewPanel.setBounds(17, 137, 374, 136) + add(deckPreviewPanel) + deckPreviewPanel.setBorder(LineBorder(Color.GRAY)) + deckPreviewPanel.setLayout(null) + labelKh.setBounds(187, 20, 72, 96) + deckPreviewPanel.add(labelKh) + labelJc.setBounds(43, 20, 72, 96) + deckPreviewPanel.add(labelJc) + labelQd.setBounds(115, 20, 72, 96) + deckPreviewPanel.add(labelQd) + labelAs.setBounds(259, 20, 72, 96) + deckPreviewPanel.add(labelAs) + lblCardDesign.setHorizontalAlignment(SwingConstants.CENTER) + lblCardDesign.setFont(Font("Tahoma", Font.BOLD, 14)) + lblCardDesign.setBounds(131, 8, 113, 17) + lblVisualPreferences.setHorizontalAlignment(SwingConstants.CENTER) + lblVisualPreferences.setBounds(178, 12, 72, 17) + add(lblVisualPreferences) + lblVisualPreferences.setFont(Font("Tahoma", Font.PLAIN, 14)) + add(separator_1) + jokerDesignPanel.setLayout(null) + jokerDesignPanel.setBorder(LineBorder(Color.GRAY)) + jokerDesignPanel.setBounds(17, 288, 374, 58) + add(jokerDesignPanel) + rdbtnClassicJokers.setBounds(6, 30, 72, 23) + jokerDesignPanel.add(rdbtnClassicJokers) + rdbtnDeveloperJokers.setBounds(80, 30, 102, 23) + jokerDesignPanel.add(rdbtnDeveloperJokers) + separator_1.setBounds(0, 38, 429, 2) + lblJokerDesign.setHorizontalAlignment(SwingConstants.CENTER) + lblJokerDesign.setFont(Font("Tahoma", Font.BOLD, 14)) + lblJokerDesign.setBounds(136, 8, 102, 17) + jokerDesignPanel.add(lblJokerDesign) + jokerPreviewPanel.setLayout(null) + jokerPreviewPanel.setBorder(LineBorder(Color.GRAY)) + jokerPreviewPanel.setBounds(17, 345, 374, 136) + add(jokerPreviewPanel) + labelJo2.setBounds(187, 20, 72, 96) + jokerPreviewPanel.add(labelJo2) + labelJo0.setBounds(43, 20, 72, 96) + jokerPreviewPanel.add(labelJo0) + labelJo1.setBounds(115, 20, 72, 96) + jokerPreviewPanel.add(labelJo1) + labelJo3.setBounds(259, 20, 72, 96) + jokerPreviewPanel.add(labelJo3) + cbFourColour.setBounds(17, 48, 135, 23) + add(cbFourColour) + backDesignPanel.setLayout(null) + backDesignPanel.setBorder(LineBorder(Color.GRAY)) + backDesignPanel.setBounds(17, 496, 374, 114) + add(backDesignPanel) + lblCardBacks.setHorizontalAlignment(SwingConstants.CENTER) + lblCardBacks.setFont(Font("Tahoma", Font.BOLD, 14)) + lblCardBacks.setBounds(127, 8, 102, 17) + backDesignPanel.add(lblCardBacks) + labelBack.setBounds(23, 9, 72, 96) + backDesignPanel.add(labelBack) + comboBoxBacks.setBounds(121, 46, 190, 22) + backDesignPanel.add(comboBoxBacks) + panelLookAndFeel.setLayout(null) + panelLookAndFeel.setBorder(LineBorder(Color.GRAY)) + panelLookAndFeel.setBounds(17, 625, 374, 114) + add(panelLookAndFeel) + lblLookFeel.setHorizontalAlignment(SwingConstants.CENTER) + lblLookFeel.setFont(Font("Tahoma", Font.BOLD, 14)) + lblLookFeel.setBounds(127, 8, 102, 17) + panelLookAndFeel.add(lblLookFeel) + comboBoxLookAndFeel.setBounds(86, 81, 190, 22) + panelLookAndFeel.add(comboBoxLookAndFeel) + val caret = DefaultCaret() + caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE) + txtpnLookAndFeelDisclaimer.setCaret(caret) + txtpnLookAndFeelDisclaimer.setText( + "Note: These options are experimental. You will need to restart for this to take effect." + ) + txtpnLookAndFeelDisclaimer.setBounds(10, 28, 354, 40) + txtpnLookAndFeelDisclaimer.setOpaque(false) + txtpnLookAndFeelDisclaimer.setBorder(BorderFactory.createEmptyBorder()) + txtpnLookAndFeelDisclaimer.setBackground(Color(0, 0, 0, 0)) + txtpnLookAndFeelDisclaimer.setEditable(false) + panelLookAndFeel.add(txtpnLookAndFeelDisclaimer) + + rdbtnClassicDesign.addActionListener(this) + rdbtnMinimalistDesign.addActionListener(this) + rdbtnClassicJokers.addActionListener(this) + rdbtnDeveloperJokers.addActionListener(this) + comboBoxBacks.addActionListener(this) + cbFourColour.addItemListener(this) + } + + /** Abstract methods */ + override fun initVariables() { + getVariablesFromPrefs() + + selectRadioButtonsBasedOnDirectories() + refreshDeckPreview() + refreshJokerPreview() + + selectCardBackBasedOnPreference() + refreshCardBackPreview() + setLookAndFeelComboBoxModel() + + hideLockedFields() + } + + override fun valid(): Boolean { + return true + } + + override fun savePreferences() { + preferenceStore.save(PreferenceSetting.DeckDesign, deckDesign) + preferenceStore.save(PreferenceSetting.JokerDesign, jokerDesign) + preferenceStore.save(PreferenceSetting.NumberOfColours, numberOfColours) + preferenceStore.save(PreferenceSetting.CardBacks, cardBacks) + preferenceStore.save( + PreferenceSetting.LookAndFeel, + comboBoxLookAndFeel.selectedItem as String, + ) + + ScreenCache.get().fireAppearancePreferencesChange() + } + + private fun getVariablesFromPrefs() { + deckDesign = getPreference(PreferenceSetting.DeckDesign) + jokerDesign = getPreference(PreferenceSetting.JokerDesign) + numberOfColours = getPreference(PreferenceSetting.NumberOfColours) + cardBacks = getPreference(PreferenceSetting.CardBacks) + lookAndFeel = getPreference(PreferenceSetting.LookAndFeel) + } + + private fun hideLockedFields() { + toggleLockedComponent(cbFourColour, Reward.FourColours) + toggleLockedComponent(rdbtnMinimalistDesign, Reward.MinimalistDeck) + toggleLockedComponent(rdbtnDeveloperJokers, Reward.DeveloperSet) + } + + private fun refreshDeckPreview() { + val jackClubs = GameUtil.getImageForCard("Jc", deckDesign, jokerDesign, numberOfColours) + val queenDiamonds = GameUtil.getImageForCard("Qd", deckDesign, jokerDesign, numberOfColours) + val kingHearts = GameUtil.getImageForCard("Kh", deckDesign, jokerDesign, numberOfColours) + val aceSpades = GameUtil.getImageForCard("As", deckDesign, jokerDesign, numberOfColours) + labelJc.setIcon(jackClubs) + labelQd.setIcon(queenDiamonds) + labelKh.setIcon(kingHearts) + labelAs.setIcon(aceSpades) + } + + private fun refreshJokerPreview() { + val jo0 = GameUtil.getImageForCard("Jo0", deckDesign, jokerDesign, numberOfColours) + val jo1 = GameUtil.getImageForCard("Jo1", deckDesign, jokerDesign, numberOfColours) + val jo2 = GameUtil.getImageForCard("Jo2", deckDesign, jokerDesign, numberOfColours) + val jo3 = GameUtil.getImageForCard("Jo3", deckDesign, jokerDesign, numberOfColours) + labelJo0.setIcon(jo0) + labelJo1.setIcon(jo1) + labelJo2.setIcon(jo2) + labelJo3.setIcon(jo3) + } + + private fun selectCardBackBasedOnPreference() { + val backs = initialiseBacksVector() + + val model: ComboBoxModel> = DisabledComboBoxModel(backs) + comboBoxBacks.setModel(model) + + var selectedItem = getSelectedItemForCode(backs, cardBacks) + if (selectedItem == null) { + selectedItem = ComboBoxItem("backBlue", "Blue") + } + + comboBoxBacks.setSelectedItem(selectedItem) + } + + private fun initialiseBacksVector(): Vector> { + val backs = Vector>() + + backs.addElement(ComboBoxItem("backBlue", "Blue")) + backs.addElement(ComboBoxItem("backRed", "Red")) + + addIfUnlocked(backs, ComboBoxItem("backGreen", "Green"), Reward.FourColours) + addIfUnlocked(backs, ComboBoxItem("backPurple", "Purple"), Reward.NegativeJacks) + addIfUnlocked(backs, ComboBoxItem("backOrange", "Orange"), Reward.Blind) + addIfUnlocked( + backs, + ComboBoxItem("backLightBlue", "Light Blue"), + Reward.MinimalistDeck, + ) + addIfUnlocked(backs, ComboBoxItem("backPink", "Pink"), Reward.Vectropy) + addIfUnlocked(backs, ComboBoxItem("backSilver", "Silver"), Reward.CardReveal) + addIfUnlocked(backs, ComboBoxItem("backGold", "Gold"), Reward.ExtraSuits) + addIfUnlocked(backs, ComboBoxItem("backMatrix", "Matrix"), Reward.Illegal) + addIfUnlocked(backs, ComboBoxItem("backCosmic", "Cosmic"), Reward.DeveloperSet) + addIfUnlocked(backs, ComboBoxItem("backRainbow", "Rainbow"), Reward.Cheats) + + return backs + } + + private fun addIfUnlocked( + backs: Vector>, + item: ComboBoxItem, + reward: Reward, + ) { + if (reward.isUnlocked()) { + backs.addElement(item) + } else { + val disabledItem = + ComboBoxItem("", reward.threshold.toString() + " achievements to unlock") + disabledItem.isEnabled = false + backs.addElement(disabledItem) + } + } + + private fun setLookAndFeelComboBoxModel() { + val backs = Vector() + for (info in UIManager.getInstalledLookAndFeels()) { + val lookAndFeelName = info.getName() + backs.add(lookAndFeelName) + } + + val model: ComboBoxModel = DefaultComboBoxModel(backs) + comboBoxLookAndFeel.setModel(model) + comboBoxLookAndFeel.setSelectedItem(lookAndFeel) + } + + private fun getSelectedItemForCode( + backs: Vector>, + code: String?, + ): ComboBoxItem? { + val size = backs.size + for (i in 0..? + if (selection == null) { + cardBacks = comboBoxBacks.getItemAt(0)!!.getHiddenData() + } else { + cardBacks = selection.getHiddenData() + } + + val back = ImageIcon(javaClass.getResource("/backs/" + cardBacks + ".png")) + labelBack.setIcon(back) + } + + private fun selectRadioButtonsBasedOnDirectories() { + cbFourColour.setSelected(numberOfColours == FOUR_COLOURS) + + if (deckDesign == DECK_DESIGN_CLASSIC) { + rdbtnClassicDesign.setSelected(true) + } else if (deckDesign == DECK_DESIGN_ALTERNATE) { + rdbtnMinimalistDesign.setSelected(true) + } + + if (jokerDesign == JOKER_DESIGN_CLASSIC) { + rdbtnClassicJokers.setSelected(true) + } else if (jokerDesign == JOKER_DESIGN_DEVELOPERS) { + rdbtnDeveloperJokers.setSelected(true) + } + } + + override fun actionPerformed(arg0: ActionEvent) { + val source = arg0.getSource() + if (source === rdbtnClassicDesign) { + deckDesign = DECK_DESIGN_CLASSIC + refreshDeckPreview() + } else if (source === rdbtnMinimalistDesign) { + deckDesign = DECK_DESIGN_ALTERNATE + refreshDeckPreview() + } else if (source === rdbtnClassicJokers) { + jokerDesign = JOKER_DESIGN_CLASSIC + refreshJokerPreview() + } else if (source === rdbtnDeveloperJokers) { + jokerDesign = JOKER_DESIGN_DEVELOPERS + refreshJokerPreview() + } else if (source === comboBoxBacks) { + refreshCardBackPreview() + } + } + + override fun itemStateChanged(arg0: ItemEvent?) { + numberOfColours = + if (cbFourColour.isSelected) { + FOUR_COLOURS + } else { + TWO_COLOURS + } + + refreshDeckPreview() + refreshJokerPreview() + } +} diff --git a/client/src/main/kotlin/screen/preference/PreferencesPanelGameplay.kt b/client/src/main/kotlin/screen/preference/PreferencesPanelGameplay.kt new file mode 100644 index 00000000..47fef4dc --- /dev/null +++ b/client/src/main/kotlin/screen/preference/PreferencesPanelGameplay.kt @@ -0,0 +1,303 @@ +package screen.preference + +import achievement.Reward +import game.GameMode +import java.awt.FlowLayout +import java.awt.Font +import java.awt.GridLayout +import java.awt.event.ActionEvent +import java.awt.event.ItemEvent +import java.awt.event.ItemListener +import javax.swing.ButtonGroup +import javax.swing.JCheckBox +import javax.swing.JLabel +import javax.swing.JPanel +import javax.swing.JRadioButton +import javax.swing.JSeparator +import javax.swing.JSlider +import javax.swing.JSpinner +import javax.swing.SpinnerNumberModel +import javax.swing.border.EmptyBorder +import javax.swing.border.TitledBorder +import javax.swing.event.ChangeEvent +import javax.swing.event.ChangeListener +import kotlin.math.max +import preference.PreferenceSetting +import preference.getPreference +import util.ClientGlobals.preferenceStore +import util.Registry + +class PreferencesPanelGameplay(parent: PreferencesDialog) : + AbstractPreferencesPanel(parent), ChangeListener, ItemListener, Registry { + private var gameMode = GameMode.Entropy + private var includeJokers = false + private var numberOfCards = 5 + private var jokerQuantity = 2 + private var jokerValue = 2 + private var playBlind = false + private var playWithHandicap = false + private var handicapAmount = 1 + private var includeStars = false + private var includeMoons = false + private var negativeJacks = false + private var cardReveal = false + + private val lblGameplay = JLabel("Gameplay") + private val separatorTitle = JSeparator() + private val panelGameMode = JPanel() + private val bgMode = ButtonGroup() + private val rdbtnEntropy = JRadioButton("Entropy") + private val rdbtnVectropy = JRadioButton("Vectropy") + private val panelStartingCards = JPanel() + private val numberOfCardsSlider = JSlider() + private val panelGameplay = JPanel() + private val handicapPanel = JPanel() + private val cbHandicap = JCheckBox("Handicap:") + private val handicapAmountSpinner = JSpinner() + private val cbPlayBlind = JCheckBox("Play Blind") + private val cbPlayersRevealCards = JCheckBox("Players reveal cards") + private val panelDeck = JPanel() + private val panelJokers = JPanel() + private val cbJokers = JCheckBox("Jokers") + private val jokerQuantitySpinner = JSpinner() + private val lblWorth = JLabel("worth") + private val jokerValueSpinner = JSpinner() + private val cbNegativeJacks = JCheckBox("Jacks worth -1") + private val cbIncludeMoons = JCheckBox("Include Moons") + private val cbIncludeStars = JCheckBox("Include Stars") + private val lblWarning = + JLabel("Note: Changes will not take effect until you start a new game.") + + init { + setLayout(null) + separatorTitle.setBounds(0, 38, 429, 2) + add(separatorTitle) + lblGameplay.setBounds(184, 12, 60, 17) + add(lblGameplay) + lblGameplay.setFont(Font("Tahoma", Font.PLAIN, 14)) + lblWarning.setBounds(65, 395, 304, 14) + add(lblWarning) + lblWarning.setFont(Font("Tahoma", Font.ITALIC, 11)) + panelGameMode.setBorder( + TitledBorder(null, "Mode", TitledBorder.LEADING, TitledBorder.TOP, null, null) + ) + panelGameMode.setBounds(20, 51, 165, 73) + add(panelGameMode) + panelGameMode.setLayout(FlowLayout(FlowLayout.LEADING, 5, 10)) + panelGameMode.add(rdbtnEntropy) + rdbtnEntropy.setFont(Font("Tahoma", Font.PLAIN, 11)) + bgMode.add(rdbtnEntropy) + panelGameMode.add(rdbtnVectropy) + rdbtnVectropy.setFont(Font("Tahoma", Font.PLAIN, 11)) + bgMode.add(rdbtnVectropy) + panelDeck.setBorder( + TitledBorder(null, "Deck", TitledBorder.LEADING, TitledBorder.TOP, null, null) + ) + panelDeck.setBounds(20, 253, 393, 131) + add(panelDeck) + panelDeck.setLayout(GridLayout(0, 1, 0, 0)) + val fl_panelJokers = panelJokers.layout as FlowLayout + fl_panelJokers.setAlignment(FlowLayout.LEFT) + panelJokers.setBorder(EmptyBorder(0, -5, 0, 0)) + panelDeck.add(panelJokers) + panelJokers.add(cbJokers) + cbJokers.setFont(Font("Tahoma", Font.PLAIN, 11)) + jokerQuantitySpinner.setFont(Font("Tahoma", Font.PLAIN, 11)) + panelJokers.add(jokerQuantitySpinner) + lblWorth.setFont(Font("Tahoma", Font.PLAIN, 11)) + panelJokers.add(lblWorth) + jokerValueSpinner.setFont(Font("Tahoma", Font.PLAIN, 11)) + panelJokers.add(jokerValueSpinner) + cbJokers.addItemListener(this) + panelDeck.add(cbNegativeJacks) + cbNegativeJacks.setSelected(false) + cbNegativeJacks.setFont(Font("Tahoma", Font.PLAIN, 11)) + panelDeck.add(cbIncludeMoons) + cbIncludeMoons.setFont(Font("Tahoma", Font.PLAIN, 11)) + panelDeck.add(cbIncludeStars) + cbIncludeStars.setFont(Font("Tahoma", Font.PLAIN, 11)) + panelGameplay.setBorder( + TitledBorder(null, "Gameplay", TitledBorder.LEADING, TitledBorder.TOP, null, null) + ) + panelGameplay.setBounds(20, 135, 393, 107) + add(panelGameplay) + panelGameplay.setLayout(GridLayout(0, 1, 0, 0)) + handicapPanel.setBorder(EmptyBorder(0, -5, 0, 0)) + val flowLayout_1 = handicapPanel.layout as FlowLayout + flowLayout_1.setAlignment(FlowLayout.LEADING) + panelGameplay.add(handicapPanel) + handicapPanel.add(cbHandicap) + cbHandicap.setFont(Font("Tahoma", Font.PLAIN, 11)) + cbHandicap.setToolTipText("Start with fewer cards than your opponents.") + handicapAmountSpinner.setFont(Font("Tahoma", Font.PLAIN, 11)) + handicapPanel.add(handicapAmountSpinner) + handicapAmountSpinner.setToolTipText("Start with this many cards less than your opponents.") + cbHandicap.addItemListener(this) + panelGameplay.add(cbPlayBlind) + cbPlayBlind.setFont(Font("Tahoma", Font.PLAIN, 11)) + cbPlayBlind.setToolTipText( + "Your hand will be face-down each round until you choose to view it manually." + ) + cbPlayersRevealCards.setFont(Font("Tahoma", Font.PLAIN, 11)) + panelGameplay.add(cbPlayersRevealCards) + panelStartingCards.setBorder( + TitledBorder(null, "Starting cards", TitledBorder.LEADING, TitledBorder.TOP, null, null) + ) + panelStartingCards.setBounds(195, 51, 218, 73) + add(panelStartingCards) + numberOfCardsSlider.setFont(Font("Tahoma", Font.PLAIN, 11)) + panelStartingCards.add(numberOfCardsSlider) + numberOfCardsSlider.setMinorTickSpacing(1) + numberOfCardsSlider.setPaintTicks(true) + numberOfCardsSlider.setPaintLabels(true) + numberOfCardsSlider.setMajorTickSpacing(4) + numberOfCardsSlider.setToolTipText("") + numberOfCardsSlider.setMinimum(1) + numberOfCardsSlider.setMaximum(5) + numberOfCardsSlider.addChangeListener(this) + handicapAmountSpinner.addChangeListener(this) + + rdbtnEntropy.addActionListener(this) + rdbtnVectropy.addActionListener(this) + } + + override fun initVariables() { + this.getVariablesFromPreferences() + + cbJokers.setSelected(includeJokers) + cbNegativeJacks.setSelected(negativeJacks) + cbPlayersRevealCards.setSelected(cardReveal) + jokerQuantitySpinner.setModel(SpinnerNumberModel(jokerQuantity, 1, 4, 1)) + jokerValueSpinner.setModel(SpinnerNumberModel(jokerValue, 2, 4, 1)) + numberOfCardsSlider.setValue(numberOfCards) + jokerQuantitySpinner.value = jokerQuantity + jokerValueSpinner.value = jokerValue + cbPlayBlind.setSelected(playBlind) + cbHandicap.setSelected(playWithHandicap) + jokerQuantitySpinner.setEnabled(includeJokers) + lblWorth.setEnabled(includeJokers) + jokerValueSpinner.setEnabled(includeJokers) + handicapAmountSpinner.setEnabled(playWithHandicap) + + adjustHandicapSpinner() + + cbIncludeStars.setSelected(includeStars) + cbIncludeMoons.setSelected(includeMoons) + + rdbtnEntropy.setSelected(gameMode == GameMode.Entropy) + rdbtnVectropy.setSelected(gameMode == GameMode.Vectropy) + + hideLockedFields() + } + + override fun valid(): Boolean { + return true + } + + override fun savePreferences() { + numberOfCards = numberOfCardsSlider.value + negativeJacks = cbNegativeJacks.isSelected + cardReveal = cbPlayersRevealCards.isSelected + jokerQuantity = if (includeJokers) jokerQuantitySpinner.value as Int else 0 + jokerValue = jokerValueSpinner.value as Int + handicapAmount = handicapAmountSpinner.value as Int + playBlind = cbPlayBlind.isSelected + includeStars = cbIncludeStars.isSelected + includeMoons = cbIncludeMoons.isSelected + + Registry.prefs.putInt(Registry.SHARED_INT_NUMBER_OF_CARDS, numberOfCards) + Registry.prefs.putBoolean(Registry.SHARED_BOOLEAN_NEGATIVE_JACKS, negativeJacks) + Registry.prefs.putInt(Registry.SHARED_INT_JOKER_QUANTITY, jokerQuantity) + Registry.prefs.putInt(Registry.SHARED_INT_JOKER_VALUE, jokerValue) + + preferenceStore.save(PreferenceSetting.PlayWithHandicap, playWithHandicap) + preferenceStore.save(PreferenceSetting.HandicapAmount, handicapAmount) + preferenceStore.save(PreferenceSetting.PlayBlind, playBlind) + Registry.prefs.putBoolean(Registry.SHARED_BOOLEAN_INCLUDE_STARS, includeStars) + Registry.prefs.putBoolean(Registry.SHARED_BOOLEAN_INCLUDE_MOONS, includeMoons) + Registry.prefs.putBoolean(Registry.SHARED_BOOLEAN_CARD_REVEAL, cardReveal) + preferenceStore.save(PreferenceSetting.GameMode, gameMode.name) + } + + private fun getVariablesFromPreferences() { + numberOfCards = Registry.prefs.getInt(Registry.SHARED_INT_NUMBER_OF_CARDS, 5) + jokerQuantity = Registry.prefs.getInt(Registry.SHARED_INT_JOKER_QUANTITY, 2) + includeJokers = jokerQuantity > 0 + jokerValue = Registry.prefs.getInt(Registry.SHARED_INT_JOKER_VALUE, 2) + playWithHandicap = getPreference(PreferenceSetting.PlayWithHandicap) + handicapAmount = getPreference(PreferenceSetting.HandicapAmount) + playBlind = getPreference(PreferenceSetting.PlayBlind) + includeStars = Registry.prefs.getBoolean(Registry.SHARED_BOOLEAN_INCLUDE_STARS, false) + includeMoons = Registry.prefs.getBoolean(Registry.SHARED_BOOLEAN_INCLUDE_MOONS, false) + negativeJacks = Registry.prefs.getBoolean(Registry.SHARED_BOOLEAN_NEGATIVE_JACKS, false) + cardReveal = Registry.prefs.getBoolean(Registry.SHARED_BOOLEAN_CARD_REVEAL, false) + gameMode = GameMode.valueOf(getPreference(PreferenceSetting.GameMode)) + } + + private fun adjustHandicapSpinner() { + if (numberOfCards == 1) { + cbHandicap.setSelected(false) + cbHandicap.setEnabled(false) + handicapAmountSpinner.setEnabled(false) + } else { + cbHandicap.setEnabled(true) + handicapAmountSpinner.setEnabled(cbHandicap.isSelected) + + val newMax = max(1, numberOfCards - 1) + if (handicapAmount > newMax) { + handicapAmount = newMax + } + + handicapAmountSpinner.setModel(SpinnerNumberModel(handicapAmount, 1, newMax, 1)) + } + } + + private fun hideLockedFields() { + toggleLockedComponent(cbNegativeJacks, Reward.NegativeJacks) + toggleLockedComponent(cbPlayBlind, Reward.Blind) + toggleLockedComponent(rdbtnVectropy, Reward.Vectropy) + toggleLockedComponent(cbPlayersRevealCards, Reward.CardReveal) + toggleLockedComponent(cbIncludeMoons, Reward.ExtraSuits) + toggleLockedComponent(cbIncludeStars, Reward.ExtraSuits) + } + + override fun actionPerformed(arg0: ActionEvent) { + val originalGameMode: GameMode? = gameMode + + val source = arg0.getSource() + if (source === rdbtnEntropy) { + gameMode = GameMode.Entropy + } else if (source === rdbtnVectropy) { + gameMode = GameMode.Vectropy + } + + if (originalGameMode != gameMode) { + parentDialog.gameModeChanged(gameMode) + } + } + + override fun stateChanged(arg0: ChangeEvent) { + val source = arg0.getSource() + if (source === numberOfCardsSlider) { + if (!numberOfCardsSlider.valueIsAdjusting) { + numberOfCards = numberOfCardsSlider.value + adjustHandicapSpinner() + } + } else if (source === handicapAmountSpinner) { + handicapAmount = handicapAmountSpinner.value as Int + } + } + + override fun itemStateChanged(arg0: ItemEvent) { + val source = arg0.getSource() + if (source === cbJokers) { + includeJokers = cbJokers.isSelected + lblWorth.setEnabled(includeJokers) + jokerQuantitySpinner.setEnabled(includeJokers) + jokerValueSpinner.setEnabled(includeJokers) + } else if (source === cbHandicap) { + playWithHandicap = cbHandicap.isSelected + handicapAmountSpinner.setEnabled(playWithHandicap) + } + } +} diff --git a/client/src/main/kotlin/screen/preference/PreferencesPanelMisc.kt b/client/src/main/kotlin/screen/preference/PreferencesPanelMisc.kt new file mode 100644 index 00000000..a8b15c90 --- /dev/null +++ b/client/src/main/kotlin/screen/preference/PreferencesPanelMisc.kt @@ -0,0 +1,281 @@ +package screen.preference + +import java.awt.Font +import java.awt.event.ActionEvent +import java.awt.event.ItemEvent +import java.awt.event.ItemListener +import java.io.File +import javax.swing.ButtonGroup +import javax.swing.JButton +import javax.swing.JCheckBox +import javax.swing.JFileChooser +import javax.swing.JLabel +import javax.swing.JOptionPane +import javax.swing.JRadioButton +import javax.swing.JSeparator +import javax.swing.JSpinner +import javax.swing.JTextField +import javax.swing.SpinnerNumberModel +import javax.swing.SwingConstants +import preference.GAME_SPEED_FAST +import preference.GAME_SPEED_MEDIUM +import preference.GAME_SPEED_SLOW +import preference.PreferenceSetting +import preference.getPreference +import util.ClientGlobals.preferenceStore +import util.DialogUtilNew +import util.ReplayFileUtil +import utils.CoreGlobals.logger + +class PreferencesPanelMisc(parent: PreferencesDialog) : + AbstractPreferencesPanel(parent), ItemListener { + private var autosave = false + private var gameSpeed: Int = GAME_SPEED_MEDIUM + private var saveReplays = false + private var replayDirectory = "" + private var openReplayOnFirstRound = false + private var autoStartNextRound = false + private var autoStartSeconds = 2 // 2 seconds + private var popUpRoomsOnline = true + private var checkForUpdates = true + + private val lblOtherOptions = JLabel("Other Options") + private val separator_3 = JSeparator() + private val fc = JFileChooser() + private val chosenDirectory = JTextField() + private val chckbxSaveReplays = JCheckBox("Save replays") + private val btnSelectDirectory = JButton("...") + private val chckbxAutosave = JCheckBox("Autosave on exit") + private val bgSpeed = ButtonGroup() + private val rdbtnSlow = JRadioButton("Slow") + private val rdbtnMedium = JRadioButton("Medium") + private val rdbtnFast = JRadioButton("Fast") + private val lblGameSpeed = JLabel("Game speed") + private val chckbxAutoStartNextRound = JCheckBox("Automatically start next round after") + private val chckbxPopUpRooms = JCheckBox("Pop up online rooms on my turn") + private val spinnerAutoStartSeconds = JSpinner() + private val lblSeconds = JLabel("seconds") + private val lblReplayViewerDefaults = JLabel("Replay viewer default") + private val bgReplayRound = ButtonGroup() + private val rdbtnFirstRound = JRadioButton("First Round") + private val rdbtnLastRound = JRadioButton("Last Round") + private val chckbxCheckForUpdates = JCheckBox("Automatically check for updates") + + init { + setLayout(null) + + bgReplayRound.add(rdbtnFirstRound) + bgReplayRound.add(rdbtnLastRound) + bgSpeed.add(rdbtnSlow) + bgSpeed.add(rdbtnMedium) + bgSpeed.add(rdbtnFast) + chckbxSaveReplays.setFont(Font("Tahoma", Font.PLAIN, 11)) + chckbxSaveReplays.setBounds(20, 67, 91, 22) + add(chckbxSaveReplays) + lblOtherOptions.setFont(Font("Tahoma", Font.PLAIN, 14)) + lblOtherOptions.setBounds(171, 12, 86, 17) + add(lblOtherOptions) + separator_3.setBounds(0, 38, 429, 2) + add(separator_3) + chosenDirectory.setBounds(116, 67, 180, 22) + chosenDirectory.setEditable(false) + add(chosenDirectory) + chosenDirectory.setColumns(10) + btnSelectDirectory.setBounds(296, 67, 20, 22) + add(btnSelectDirectory) + chckbxAutosave.setBounds(20, 180, 127, 22) + add(chckbxAutosave) + chckbxAutosave.setFont(Font("Tahoma", Font.PLAIN, 11)) + lblReplayViewerDefaults.setFont(Font("Tahoma", Font.PLAIN, 11)) + lblReplayViewerDefaults.setBounds(20, 112, 127, 14) + add(lblReplayViewerDefaults) + rdbtnFirstRound.setFont(Font("Tahoma", Font.PLAIN, 11)) + rdbtnFirstRound.setBounds(144, 109, 91, 20) + add(rdbtnFirstRound) + rdbtnLastRound.setFont(Font("Tahoma", Font.PLAIN, 11)) + rdbtnLastRound.setBounds(237, 109, 91, 20) + add(rdbtnLastRound) + lblGameSpeed.setBounds(20, 148, 86, 14) + add(lblGameSpeed) + lblGameSpeed.setHorizontalAlignment(SwingConstants.LEFT) + lblGameSpeed.setFont(Font("Tahoma", Font.PLAIN, 11)) + rdbtnSlow.setBounds(144, 144, 60, 20) + add(rdbtnSlow) + rdbtnSlow.setFont(Font("Tahoma", Font.PLAIN, 11)) + rdbtnMedium.setBounds(206, 144, 70, 20) + add(rdbtnMedium) + rdbtnMedium.setFont(Font("Tahoma", Font.PLAIN, 11)) + rdbtnFast.setBounds(274, 144, 54, 20) + add(rdbtnFast) + rdbtnFast.setFont(Font("Tahoma", Font.PLAIN, 11)) + chckbxAutoStartNextRound.setFont(Font("Tahoma", Font.PLAIN, 11)) + chckbxAutoStartNextRound.setBounds(20, 205, 208, 23) + add(chckbxAutoStartNextRound) + chckbxPopUpRooms.setFont(Font("Tahoma", Font.PLAIN, 11)) + chckbxPopUpRooms.setBounds(20, 230, 208, 23) + add(chckbxPopUpRooms) + spinnerAutoStartSeconds.setBounds(228, 205, 38, 22) + add(spinnerAutoStartSeconds) + lblSeconds.setFont(Font("Tahoma", Font.PLAIN, 11)) + lblSeconds.setBounds(275, 206, 55, 20) + add(lblSeconds) + chckbxCheckForUpdates.setFont(Font("Tahoma", Font.PLAIN, 11)) + chckbxCheckForUpdates.setBounds(20, 256, 237, 23) + add(chckbxCheckForUpdates) + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) + + rdbtnFast.addActionListener(this) + rdbtnMedium.addActionListener(this) + rdbtnSlow.addActionListener(this) + btnSelectDirectory.addActionListener(this) + chckbxSaveReplays.addItemListener(this) + chckbxAutoStartNextRound.addItemListener(this) + } + + /** Abstract methods */ + override fun initVariables() { + getVariablesFromPrefs() + + spinnerAutoStartSeconds.setModel(SpinnerNumberModel(autoStartSeconds, 1, 5, 1)) + chosenDirectory.text = "$replayDirectory\\Replays" + chckbxAutosave.setSelected(autosave) + rdbtnSlow.setSelected(gameSpeed == GAME_SPEED_SLOW) + rdbtnMedium.setSelected(gameSpeed == GAME_SPEED_MEDIUM) + rdbtnFast.setSelected(gameSpeed == GAME_SPEED_FAST) + chckbxSaveReplays.setSelected(saveReplays) + chosenDirectory.text = "$replayDirectory\\Replays" + chosenDirectory.setEnabled(saveReplays) + btnSelectDirectory.setEnabled(saveReplays) + chckbxAutoStartNextRound.setSelected(autoStartNextRound) + chckbxPopUpRooms.setSelected(popUpRoomsOnline) + chckbxCheckForUpdates.setSelected(checkForUpdates) + spinnerAutoStartSeconds.setEnabled(autoStartNextRound) + lblSeconds.setEnabled(autoStartNextRound) + spinnerAutoStartSeconds.setValue(autoStartSeconds) + rdbtnFirstRound.setSelected(openReplayOnFirstRound) + rdbtnLastRound.setSelected(!openReplayOnFirstRound) + } + + override fun valid(): Boolean { + return confirmChangeOfDirectory() + } + + override fun savePreferences() { + autosave = chckbxAutosave.isSelected + openReplayOnFirstRound = rdbtnFirstRound.isSelected + autoStartSeconds = spinnerAutoStartSeconds.value as Int + popUpRoomsOnline = chckbxPopUpRooms.isSelected + checkForUpdates = chckbxCheckForUpdates.isSelected + + preferenceStore.save(PreferenceSetting.SaveReplays, saveReplays) + preferenceStore.save(PreferenceSetting.AutoSave, autosave) + preferenceStore.save(PreferenceSetting.ReplayDirectory, replayDirectory) + preferenceStore.save(PreferenceSetting.OpenReplayOnFirstRound, openReplayOnFirstRound) + preferenceStore.save(PreferenceSetting.AutoStartNextRound, autoStartNextRound) + preferenceStore.save(PreferenceSetting.AutoStartSeconds, autoStartSeconds) + preferenceStore.save(PreferenceSetting.PopUpRooms, popUpRoomsOnline) + preferenceStore.save(PreferenceSetting.CheckForUpdates, checkForUpdates) + preferenceStore.save(PreferenceSetting.GameSpeed, gameSpeed) + } + + private fun getVariablesFromPrefs() { + autosave = getPreference(PreferenceSetting.AutoSave) + gameSpeed = getPreference(PreferenceSetting.GameSpeed) + saveReplays = getPreference(PreferenceSetting.SaveReplays) + replayDirectory = getPreference(PreferenceSetting.ReplayDirectory)!! + openReplayOnFirstRound = getPreference(PreferenceSetting.OpenReplayOnFirstRound) + autoStartNextRound = getPreference(PreferenceSetting.AutoStartNextRound) + autoStartSeconds = getPreference(PreferenceSetting.AutoStartSeconds) + popUpRoomsOnline = getPreference(PreferenceSetting.PopUpRooms) + checkForUpdates = getPreference(PreferenceSetting.CheckForUpdates) + } + + private fun confirmChangeOfDirectory(): Boolean { + val originalReplayDirectory: String = preferenceStore.get(PreferenceSetting.ReplayDirectory) + + val myExistingFiles = + File(originalReplayDirectory + "//Replays//" + ReplayFileUtil.FOLDER_PERSONAL_REPLAYS) + .listFiles() + var myExistingFilesLength = 0 + if (myExistingFiles != null) { + myExistingFilesLength = myExistingFiles.size + } + + val importedExistingFiles = + File(originalReplayDirectory + "//Replays//" + ReplayFileUtil.FOLDER_IMPORTED_REPLAYS) + .listFiles() + var importedExistingFilesLength = 0 + if (importedExistingFiles != null) { + importedExistingFilesLength = importedExistingFiles.size + } + + if ( + replayDirectory != originalReplayDirectory && + (myExistingFilesLength != 0 || importedExistingFilesLength != 0) + ) { + val choice = + DialogUtilNew.showQuestion( + "You have changed your replay directory but there are still files in the old one. " + + "\nWould you like to move these files to the new location?", + true, + ) + + if (choice == JOptionPane.YES_OPTION) { + ReplayFileUtil.moveReplays( + myExistingFiles, + importedExistingFiles, + originalReplayDirectory, + replayDirectory, + ) + } else if (choice == JOptionPane.CANCEL_OPTION) { + return false + } else { + DialogUtilNew.showInfo( + "Existing replay files were left in the old directory and will have to be deleted or moved manually." + ) + } + } + + return true + } + + private fun selectReplayDirectory() { + val returnVal = fc.showOpenDialog(this) + if (returnVal == JFileChooser.APPROVE_OPTION) { + val file = fc.getSelectedFile() + + replayDirectory = file.getPath() + chosenDirectory.setText("$replayDirectory\\Replays") + + logger.info("replay.dir", "Selected ${file.path} as replay directory") + } else { + logger.info("replay.dir", "Cancelled directory selection") + } + } + + override fun actionPerformed(arg0: ActionEvent) { + val source = arg0.getSource() + if (source === rdbtnFast) { + gameSpeed = GAME_SPEED_FAST + } else if (source === rdbtnMedium) { + gameSpeed = GAME_SPEED_MEDIUM + } else if (source === rdbtnSlow) { + gameSpeed = GAME_SPEED_SLOW + } else if (source === btnSelectDirectory) { + selectReplayDirectory() + } + } + + override fun itemStateChanged(arg0: ItemEvent) { + val source = arg0.getSource() + if (source === chckbxSaveReplays) { + saveReplays = chckbxSaveReplays.isSelected() + chosenDirectory.setEnabled(saveReplays) + btnSelectDirectory.setEnabled(saveReplays) + } else if (source === chckbxAutoStartNextRound) { + autoStartNextRound = chckbxAutoStartNextRound.isSelected() + lblSeconds.setEnabled(autoStartNextRound) + spinnerAutoStartSeconds.setEnabled(autoStartNextRound) + } + } +} diff --git a/client/src/main/kotlin/screen/preference/PreferencesPanelPlayers.kt b/client/src/main/kotlin/screen/preference/PreferencesPanelPlayers.kt new file mode 100644 index 00000000..138e7119 --- /dev/null +++ b/client/src/main/kotlin/screen/preference/PreferencesPanelPlayers.kt @@ -0,0 +1,374 @@ +package screen.preference + +import game.GameMode +import java.awt.Font +import java.awt.event.ActionEvent +import java.awt.event.ItemEvent +import java.awt.event.ItemListener +import java.awt.event.MouseEvent +import java.awt.event.MouseListener +import javax.swing.ComboBoxModel +import javax.swing.DefaultComboBoxModel +import javax.swing.JButton +import javax.swing.JCheckBox +import javax.swing.JComboBox +import javax.swing.JLabel +import javax.swing.JMenuItem +import javax.swing.JOptionPane +import javax.swing.JPopupMenu +import javax.swing.JScrollPane +import javax.swing.JSeparator +import javax.swing.JTable +import javax.swing.JTextField +import javax.swing.ListSelectionModel +import javax.swing.SwingConstants +import javax.swing.SwingUtilities +import javax.swing.table.TableModel +import javax.swing.table.TableRowSorter +import `object`.ApiStrategy +import `object`.LimitedDocument +import preference.PreferenceSetting +import preference.getPreference +import screen.ApiAmendDialog +import util.ApiUtil +import util.ClientGlobals.preferenceStore +import util.CpuStrategies +import util.DialogUtilNew +import util.TableUtil.DefaultModel +import util.TableUtil.SimpleRenderer + +class PreferencesPanelPlayers(parent: PreferencesDialog) : + AbstractPreferencesPanel(parent), MouseListener, ItemListener { + private var playerName = "Player" + private var opponentOneName = "Mark" + private var opponentTwoName = "Dave" + private var opponentThreeName = "Tom" + private var opponentTwoEnabled = false + private var opponentThreeEnabled = false + private var opponentOneStrategy: String = "Mark" + private var opponentTwoStrategy: String = "Basic" + private var opponentThreeStrategy: String = "Basic" + private var apiStrategies: List = emptyList() + private var gameMode: GameMode = GameMode.Entropy + + private val lblPlayers = JLabel("Players") + private val separator_2 = JSeparator() + private val lblPlayerName = JLabel("Player Name") + private val playerNameField = JTextField() + private val opponentOneNameField = JTextField() + private val opponentTwoNameField = JTextField() + private val opponentThreeNameField = JTextField() + private val cbOpponentTwo = JCheckBox() + private val cbOpponentThree = JCheckBox() + private val opponentOneStrat = JComboBox() + private val opponentTwoStrat = JComboBox() + private val opponentThreeStrat = JComboBox() + private val label = JLabel("Note: Changes will not take effect until you start a new game.") + private val separator_4 = JSeparator() + private val lblApiHeader = JLabel("API Options") + private val scrollPane = JScrollPane() + private val tableApiStrategies = JTable() + private val popupMenu = JPopupMenu() + private val amendItem = JMenuItem("Amend") + private val deleteItem = JMenuItem("Delete") + private val enableItem = JMenuItem("Enable") + private val btnNewApiStrategy = JButton("New API Strategy") + + init { + setLayout(null) + + separator_2.setBounds(0, 38, 434, 2) + add(separator_2) + lblPlayers.setBounds(172, 12, 70, 17) + add(lblPlayers) + lblPlayers.setHorizontalAlignment(SwingConstants.CENTER) + lblPlayers.setFont(Font("Tahoma", Font.PLAIN, 14)) + playerNameField.setDocument(LimitedDocument(10)) + opponentOneNameField.setDocument(LimitedDocument(10)) + opponentTwoNameField.setDocument(LimitedDocument(10)) + opponentThreeNameField.setDocument(LimitedDocument(10)) + opponentOneNameField.setBounds(60, 102, 86, 22) + add(opponentOneNameField) + opponentOneNameField.text = opponentOneName + opponentOneNameField.setColumns(10) + cbOpponentTwo.setBounds(22, 143, 29, 23) + add(cbOpponentTwo) + cbOpponentThree.setBounds(22, 185, 29, 23) + add(cbOpponentThree) + opponentTwoNameField.setBounds(60, 144, 86, 22) + add(opponentTwoNameField) + opponentTwoNameField.text = opponentTwoName + opponentTwoNameField.setColumns(10) + opponentThreeNameField.setBounds(60, 186, 86, 22) + add(opponentThreeNameField) + opponentThreeNameField.text = opponentThreeName + opponentThreeNameField.setColumns(10) + opponentTwoStrat.setBounds(172, 144, 197, 22) + add(opponentTwoStrat) + opponentThreeStrat.setBounds(172, 186, 197, 22) + add(opponentThreeStrat) + opponentOneStrat.setBounds(172, 102, 197, 22) + add(opponentOneStrat) + playerNameField.setBounds(212, 60, 86, 22) + add(playerNameField) + playerNameField.setColumns(10) + lblPlayerName.setBounds(122, 60, 80, 22) + add(lblPlayerName) + label.setFont(Font("Tahoma", Font.ITALIC, 11)) + label.setBounds(65, 395, 304, 14) + add(label) + lblApiHeader.setHorizontalAlignment(SwingConstants.CENTER) + lblApiHeader.setFont(Font("Tahoma", Font.PLAIN, 14)) + lblApiHeader.setBounds(171, 240, 86, 17) + add(lblApiHeader) + separator_4.setBounds(0, 265, 429, 2) + add(separator_4) + scrollPane.setBounds(17, 307, 402, 80) + add(scrollPane) + tableApiStrategies.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) + scrollPane.setViewportView(tableApiStrategies) + btnNewApiStrategy.setBounds(17, 278, 151, 23) + add(btnNewApiStrategy) + tableApiStrategies.getTableHeader().setReorderingAllowed(false) + popupMenu.add(enableItem) + popupMenu.add(amendItem) + popupMenu.add(deleteItem) + + btnNewApiStrategy.addActionListener(this) + enableItem.addActionListener(this) + deleteItem.addActionListener(this) + amendItem.addActionListener(this) + tableApiStrategies.addMouseListener(this) + cbOpponentTwo.addItemListener(this) + cbOpponentThree.addItemListener(this) + } + + /** Abstract methods */ + override fun initVariables() { + getVariablesFromPrefs() + + buildApiTable() + setPlayerNames() + setOpponentEnablementAndStrategies() + setOpponentStrategies() + } + + override fun valid(): Boolean { + val nameOne = playerNameField.getText() + val nameTwo = opponentOneNameField.getText() + val nameThree = opponentTwoNameField.getText() + val nameFour = opponentThreeNameField.getText() + + if (nameOne.isEmpty() || nameTwo.isEmpty() || nameThree.isEmpty() || nameFour.isEmpty()) { + DialogUtilNew.showError("You must enter a name for each player.") + return false + } + + return true + } + + override fun savePreferences() { + playerName = playerNameField.getText() + opponentOneName = opponentOneNameField.getText() + opponentTwoName = opponentTwoNameField.getText() + opponentThreeName = opponentThreeNameField.getText() + opponentOneStrategy = opponentOneStrat.selectedItem as String + opponentTwoStrategy = opponentTwoStrat.selectedItem as String + opponentThreeStrategy = opponentThreeStrat.selectedItem as String + + preferenceStore.save(PreferenceSetting.PlayerName, playerName) + preferenceStore.save(PreferenceSetting.OpponentOneName, opponentOneName) + preferenceStore.save(PreferenceSetting.OpponentTwoName, opponentTwoName) + preferenceStore.save(PreferenceSetting.OpponentThreeName, opponentThreeName) + preferenceStore.save(PreferenceSetting.OpponentTwoEnabled, opponentTwoEnabled) + preferenceStore.save(PreferenceSetting.OpponentThreeEnabled, opponentThreeEnabled) + preferenceStore.save(PreferenceSetting.OpponentOneStrategy, opponentOneStrategy) + preferenceStore.save(PreferenceSetting.OpponentTwoStrategy, opponentTwoStrategy) + preferenceStore.save(PreferenceSetting.OpponentThreeStrategy, opponentThreeStrategy) + + ApiUtil.saveApiStrategiesToPreferences(apiStrategies) + } + + private fun getVariablesFromPrefs() { + playerName = getPreference(PreferenceSetting.PlayerName) + opponentOneName = getPreference(PreferenceSetting.OpponentOneName) + opponentTwoName = getPreference(PreferenceSetting.OpponentTwoName) + opponentThreeName = getPreference(PreferenceSetting.OpponentThreeName) + opponentTwoEnabled = getPreference(PreferenceSetting.OpponentTwoEnabled) + opponentThreeEnabled = getPreference(PreferenceSetting.OpponentThreeEnabled) + opponentOneStrategy = getPreference(PreferenceSetting.OpponentOneStrategy) + opponentTwoStrategy = getPreference(PreferenceSetting.OpponentTwoStrategy) + opponentThreeStrategy = getPreference(PreferenceSetting.OpponentThreeStrategy) + apiStrategies = ApiUtil.getApiStrategiesFromPreferences() + + gameMode = GameMode.valueOf(getPreference(PreferenceSetting.GameMode)) + } + + private fun setPlayerNames() { + playerNameField.text = playerName + opponentOneNameField.text = opponentOneName + opponentTwoNameField.text = opponentTwoName + opponentThreeNameField.text = opponentThreeName + } + + private fun setOpponentEnablementAndStrategies() { + cbOpponentThree.setEnabled(opponentTwoEnabled) + cbOpponentTwo.setEnabled(!opponentThreeEnabled) + + cbOpponentTwo.setSelected(opponentTwoEnabled) + cbOpponentThree.setSelected(opponentThreeEnabled) + opponentTwoNameField.setEnabled(opponentTwoEnabled) + opponentThreeNameField.setEnabled(opponentThreeEnabled) + opponentTwoStrat.setEnabled(opponentTwoEnabled) + opponentThreeStrat.setEnabled(opponentThreeEnabled) + } + + private fun setOpponentStrategies() { + opponentOneStrat.setSelectedItem(opponentOneStrategy) + opponentTwoStrat.setSelectedItem(opponentTwoStrategy) + opponentThreeStrat.setSelectedItem(opponentThreeStrategy) + } + + private fun buildApiTable() { + val model = DefaultModel() + tableApiStrategies.setModel(model) + + // Columns + model.addColumn("Name") + model.addColumn("Port") + model.addColumn("Game") + model.addColumn("Messaging") + model.addColumn("Enabled") + + // Centre rendering for everything but the last column + for (i in 0..(model) + tableApiStrategies.setRowSorter(sorter) + + // Populate the rows + apiStrategies.forEach { model.addRow(it.tableModelRow) } + + updateStrategySelection(gameMode) + } + + fun updateStrategySelection(gameMode: GameMode) { + this.gameMode = gameMode + + val allStrategies = + CpuStrategies.getAllStrategies(gameMode == GameMode.Entropy, apiStrategies) + + var comboModel: ComboBoxModel = DefaultComboBoxModel(allStrategies) + opponentOneStrat.setModel(comboModel) + comboModel = DefaultComboBoxModel(allStrategies) + opponentTwoStrat.setModel(comboModel) + comboModel = DefaultComboBoxModel(allStrategies) + opponentThreeStrat.setModel(comboModel) + } + + private fun enableApi(strategy: ApiStrategy) { + val question = + "Strategy ${strategy.name} was disabled due to the following error:\n\n${strategy.error}\n\nWould you like to re-enable it?" + + val option = DialogUtilNew.showQuestion(question, false) + if (option == JOptionPane.YES_OPTION) { + strategy.error = "" + buildApiTable() + } + } + + private fun amendApi(strategy: ApiStrategy?) { + ApiAmendDialog.amendStrategy(strategy) + buildApiTable() + } + + private fun deleteApi(strategy: ApiStrategy) { + val question = "Are you sure you want to delete the " + strategy.getName() + " strategy?" + val option = DialogUtilNew.showQuestion(question, false) + if (option == JOptionPane.YES_OPTION) { + apiStrategies = apiStrategies - strategy + buildApiTable() + } + } + + private fun getSelectedStrategyFromTable(): ApiStrategy? { + val row = tableApiStrategies.selectedRow + if (row == -1) { + return null + } + + val internalRow = tableApiStrategies.convertRowIndexToModel(row) + val model = tableApiStrategies.model as DefaultModel + val name = model.getValueAt(internalRow, 0) as String + + return apiStrategies.find { it.name == name } + } + + override fun actionPerformed(arg0: ActionEvent) { + val source = arg0.getSource() + if (source === btnNewApiStrategy) { + val strategy: ApiStrategy? = ApiAmendDialog.createStrategy() + if (strategy != null) { + apiStrategies = apiStrategies + strategy + buildApiTable() + } + } else if (source === amendItem) { + getSelectedStrategyFromTable()?.let(::amendApi) + } else if (source === deleteItem) { + getSelectedStrategyFromTable()?.let(::deleteApi) + } else if (source === enableItem) { + getSelectedStrategyFromTable()?.let(::enableApi) + } + } + + override fun mousePressed(arg0: MouseEvent?) {} + + override fun mouseClicked(arg0: MouseEvent) { + val strategy: ApiStrategy? = getSelectedStrategyFromTable() + + if (SwingUtilities.isRightMouseButton(arg0)) { + val point = arg0.getPoint() + val row = tableApiStrategies.rowAtPoint(point) + if (!tableApiStrategies.isRowSelected(row)) { + val column = tableApiStrategies.columnAtPoint(point) + tableApiStrategies.changeSelection(row, column, false, false) + } + + if (strategy != null) { + enableItem.setEnabled(!strategy.isEnabled) + + // Show the popup menu + popupMenu.show(arg0.component, arg0.getX(), arg0.getY()) + } + } else if (arg0.getClickCount() == 2) { + // Double-click + if (strategy != null) { + if (!strategy.isEnabled) { + enableApi(strategy) + } else { + amendApi(strategy) + } + } + } + } + + override fun mouseExited(arg0: MouseEvent?) {} + + override fun mouseEntered(arg0: MouseEvent?) {} + + override fun mouseReleased(arg0: MouseEvent?) {} + + override fun itemStateChanged(arg0: ItemEvent) { + val source = arg0.getSource() + if (source === cbOpponentTwo) { + opponentTwoEnabled = cbOpponentTwo.isSelected + setOpponentEnablementAndStrategies() + } else if (source === cbOpponentThree) { + opponentThreeEnabled = cbOpponentThree.isSelected + setOpponentEnablementAndStrategies() + } + } +} diff --git a/core/src/main/java/util/Debug.java b/core/src/main/java/util/Debug.java index da04e529..3da865f4 100644 --- a/core/src/main/java/util/Debug.java +++ b/core/src/main/java/util/Debug.java @@ -8,6 +8,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; +@Deprecated public class Debug { private static DebugOutput output = null; From 30f99c9730e6b356f4c2b57aad3a520d4f4f2915 Mon Sep 17 00:00:00 2001 From: alyssa Date: Wed, 27 Aug 2025 08:51:10 +0100 Subject: [PATCH 07/13] finish removing old-style prefs --- client/src/main/java/screen/GameScreen.java | 11 ++++++- client/src/main/java/util/ApiUtil.java | 22 ++++++++++--- .../kotlin/preference/PreferenceSetting.kt | 8 +++++ .../preference/PreferencesPanelGameplay.kt | 31 ++++++++++--------- core/src/main/java/util/Registry.java | 11 ------- 5 files changed, 52 insertions(+), 31 deletions(-) diff --git a/client/src/main/java/screen/GameScreen.java b/client/src/main/java/screen/GameScreen.java index 9861a22a..a4d724da 100644 --- a/client/src/main/java/screen/GameScreen.java +++ b/client/src/main/java/screen/GameScreen.java @@ -317,7 +317,16 @@ private void getNewGameVariablesFromRegistry() opponentTwo.setStrategy(getPreference(PreferenceSetting.OpponentTwoStrategy)); opponentThree.setStrategy(getPreference(PreferenceSetting.OpponentThreeStrategy)); - settings = GameSettings.fromRegistry(prefs, getGameMode()); + settings = new GameSettings( + getGameMode(), + getPreference(PreferenceSetting.StartingCards), + getPreference(PreferenceSetting.JokerQuantity), + getPreference(PreferenceSetting.JokerValue), + getPreference(PreferenceSetting.IncludeMoons), + getPreference(PreferenceSetting.IncludeStars), + getPreference(PreferenceSetting.NegativeJacks), + getPreference(PreferenceSetting.CardReveal), + true); handPanel.fireAppearancePreferencesChange(); handPanel.initPlayerNames(); diff --git a/client/src/main/java/util/ApiUtil.java b/client/src/main/java/util/ApiUtil.java index 73dca38b..10234324 100644 --- a/client/src/main/java/util/ApiUtil.java +++ b/client/src/main/java/util/ApiUtil.java @@ -25,7 +25,7 @@ import static preference.PreferenceSettingKt.getPreference; import static util.ClientGlobals.preferenceStore; -public class ApiUtil implements Registry +public class ApiUtil { public static final String API_PREFIX = "API: "; public static final String MESSAGE_TYPE_XML = "XML"; @@ -33,6 +33,14 @@ public class ApiUtil implements Registry private static final String ROOT_TAG_API_MESSAGE = "ApiMessage"; private static final InetAddress INET_ADDRESS_LOCALHOST = MessageUtil.factoryInetAddress("localhost"); + + private static final String PREFERENCES_TAG_API = "Api"; + private static final String PREFERENCES_ATTR_API_NAME = "ApiName"; + private static final String PREFERENCES_ATTR_PORT_NUMNER = "PortNumber"; + private static final String PREFERENCES_ATTR_MESSAGE_TYPE = "MessageType"; + private static final String PREFERENCES_ATTR_SUPPORTS_ENTROPY = "Entropy"; + private static final String PREFERENCES_ATTR_SUPPORTS_VECTROPY = "Vectropy"; + private static final String PREFERENCES_ATTR_ERROR = "Error"; //Cache this for speed in the simulator private static HashMap hmNameToApiStrategy = null; @@ -252,8 +260,13 @@ private static void showMalformedResponseError(String response) private static void initialiseStrategyHashMap() { HashMap temp = new HashMap<>(); - - Document apiXml = RegistryUtil.getAttributeXml(prefs, PREFERENCES_XML_API_SETTINGS); + + String apiStrategies = getPreference(PreferenceSetting.ApiStrategies); + if (apiStrategies.isBlank()) { + return; + } + + Document apiXml = XmlUtil.getDocumentFromXmlString(apiStrategies); if (apiXml == null) { hmNameToApiStrategy = temp; @@ -346,7 +359,8 @@ public static void saveApiStrategiesToPreferences(List strategies) apiDoc.appendChild(rootElement); //Save to the Registry - RegistryUtil.setAttributeXml(prefs, PREFERENCES_XML_API_SETTINGS, apiDoc); + String xmlStr = XmlUtil.getStringFromDocument(apiDoc); + preferenceStore.save(PreferenceSetting.ApiStrategies, xmlStr); //Clear the cache clearCache(); diff --git a/client/src/main/kotlin/preference/PreferenceSetting.kt b/client/src/main/kotlin/preference/PreferenceSetting.kt index 2803357f..b06ce523 100644 --- a/client/src/main/kotlin/preference/PreferenceSetting.kt +++ b/client/src/main/kotlin/preference/PreferenceSetting.kt @@ -23,6 +23,13 @@ object PreferenceSetting { @JvmField val PlayWithHandicap = Setting("playWithHandicap", false) @JvmField val HandicapAmount = Setting("handicapAmount", 1) @JvmField val PlayBlind = Setting("playBlind", false) + @JvmField val StartingCards = Setting("startingCards", 5) + @JvmField val JokerQuantity = Setting("jokerQuantity", 2) + @JvmField val JokerValue = Setting("jokerValue", 2) + @JvmField val NegativeJacks = Setting("negativeJacks", false) + @JvmField val IncludeMoons = Setting("includeMoons", false) + @JvmField val IncludeStars = Setting("includeStars", false) + @JvmField val CardReveal = Setting("cardReveal", false) // Players @JvmField val PlayerName = Setting("playerName", "Player") @@ -34,6 +41,7 @@ object PreferenceSetting { @JvmField val OpponentThreeStrategy = Setting("opponentThreeStrategy", STRATEGY_BASIC) @JvmField val OpponentTwoEnabled = Setting("opponentTwoEnabled", false) @JvmField val OpponentThreeEnabled = Setting("opponentThreeEnabled", false) + @JvmField val ApiStrategies = Setting("apiStrategies", "") // Appearance @JvmField val DeckDesign = Setting("deckDesign", DECK_DESIGN_CLASSIC) diff --git a/client/src/main/kotlin/screen/preference/PreferencesPanelGameplay.kt b/client/src/main/kotlin/screen/preference/PreferencesPanelGameplay.kt index 47fef4dc..1bd1e3ec 100644 --- a/client/src/main/kotlin/screen/preference/PreferencesPanelGameplay.kt +++ b/client/src/main/kotlin/screen/preference/PreferencesPanelGameplay.kt @@ -205,33 +205,34 @@ class PreferencesPanelGameplay(parent: PreferencesDialog) : includeStars = cbIncludeStars.isSelected includeMoons = cbIncludeMoons.isSelected - Registry.prefs.putInt(Registry.SHARED_INT_NUMBER_OF_CARDS, numberOfCards) - Registry.prefs.putBoolean(Registry.SHARED_BOOLEAN_NEGATIVE_JACKS, negativeJacks) - Registry.prefs.putInt(Registry.SHARED_INT_JOKER_QUANTITY, jokerQuantity) - Registry.prefs.putInt(Registry.SHARED_INT_JOKER_VALUE, jokerValue) + preferenceStore.save(PreferenceSetting.StartingCards, numberOfCards) + preferenceStore.save(PreferenceSetting.StartingCards, numberOfCards) + preferenceStore.save(PreferenceSetting.NegativeJacks, negativeJacks) + preferenceStore.save(PreferenceSetting.JokerQuantity, jokerQuantity) + preferenceStore.save(PreferenceSetting.JokerValue, jokerValue) preferenceStore.save(PreferenceSetting.PlayWithHandicap, playWithHandicap) preferenceStore.save(PreferenceSetting.HandicapAmount, handicapAmount) preferenceStore.save(PreferenceSetting.PlayBlind, playBlind) - Registry.prefs.putBoolean(Registry.SHARED_BOOLEAN_INCLUDE_STARS, includeStars) - Registry.prefs.putBoolean(Registry.SHARED_BOOLEAN_INCLUDE_MOONS, includeMoons) - Registry.prefs.putBoolean(Registry.SHARED_BOOLEAN_CARD_REVEAL, cardReveal) + preferenceStore.save(PreferenceSetting.IncludeStars, includeStars) + preferenceStore.save(PreferenceSetting.IncludeMoons, includeMoons) + preferenceStore.save(PreferenceSetting.CardReveal, cardReveal) preferenceStore.save(PreferenceSetting.GameMode, gameMode.name) } private fun getVariablesFromPreferences() { - numberOfCards = Registry.prefs.getInt(Registry.SHARED_INT_NUMBER_OF_CARDS, 5) - jokerQuantity = Registry.prefs.getInt(Registry.SHARED_INT_JOKER_QUANTITY, 2) + numberOfCards = getPreference(PreferenceSetting.StartingCards) + jokerQuantity = getPreference(PreferenceSetting.JokerQuantity) includeJokers = jokerQuantity > 0 - jokerValue = Registry.prefs.getInt(Registry.SHARED_INT_JOKER_VALUE, 2) + jokerValue = getPreference(PreferenceSetting.JokerValue) playWithHandicap = getPreference(PreferenceSetting.PlayWithHandicap) handicapAmount = getPreference(PreferenceSetting.HandicapAmount) playBlind = getPreference(PreferenceSetting.PlayBlind) - includeStars = Registry.prefs.getBoolean(Registry.SHARED_BOOLEAN_INCLUDE_STARS, false) - includeMoons = Registry.prefs.getBoolean(Registry.SHARED_BOOLEAN_INCLUDE_MOONS, false) - negativeJacks = Registry.prefs.getBoolean(Registry.SHARED_BOOLEAN_NEGATIVE_JACKS, false) - cardReveal = Registry.prefs.getBoolean(Registry.SHARED_BOOLEAN_CARD_REVEAL, false) - gameMode = GameMode.valueOf(getPreference(PreferenceSetting.GameMode)) + includeStars = getPreference(PreferenceSetting.IncludeStars) + includeMoons = getPreference(PreferenceSetting.IncludeMoons) + negativeJacks = getPreference(PreferenceSetting.NegativeJacks) + cardReveal = getPreference(PreferenceSetting.CardReveal) + gameMode = GameMode.valueOf(getPreference(PreferenceSetting.GameMode)) } private fun adjustHandicapSpinner() { diff --git a/core/src/main/java/util/Registry.java b/core/src/main/java/util/Registry.java index 7ad3a820..0916d959 100644 --- a/core/src/main/java/util/Registry.java +++ b/core/src/main/java/util/Registry.java @@ -10,7 +10,6 @@ public interface Registry //Actual preference wrappers public static final Preferences savedGame = Preferences.userRoot().node("entropySavedgameNone"); - public static final Preferences prefs = Preferences.userRoot().node("entropyPreferencesTuuug"); public static final Preferences inGameReplay = Preferences.userRoot().node("entropyReplayCurrent"); public static final Preferences fileReplay = Preferences.userRoot().node("entropyReplayFile"); public static final Preferences tempReplayStore = Preferences.userRoot().node("entropyTemp"); @@ -32,16 +31,6 @@ public interface Registry public static final String SHARED_INT_JOKER_QUANTITY = "jokerQuantity"; public static final String SHARED_INT_NUMBER_OF_CARDS = "numberOfCards"; - //prefs - public static final String PREFERENCES_XML_API_SETTINGS = "apiSettings"; - public static final String PREFERENCES_TAG_API = "Api"; - public static final String PREFERENCES_ATTR_API_NAME = "ApiName"; - public static final String PREFERENCES_ATTR_PORT_NUMNER = "PortNumber"; - public static final String PREFERENCES_ATTR_MESSAGE_TYPE = "MessageType"; - public static final String PREFERENCES_ATTR_SUPPORTS_ENTROPY = "Entropy"; - public static final String PREFERENCES_ATTR_SUPPORTS_VECTROPY = "Vectropy"; - public static final String PREFERENCES_ATTR_ERROR = "Error"; - //replay public static final String REPLAY_STRING_OPPONENT_THREE_HAND = "opponentThreeHand"; public static final String REPLAY_STRING_OPPONENT_TWO_HAND = "opponentTwoHand"; From 8d97086bfd5dfc5e30ddafebde12fda9bb37e678 Mon Sep 17 00:00:00 2001 From: alyssa Date: Wed, 27 Aug 2025 08:52:35 +0100 Subject: [PATCH 08/13] finish removing old-style prefs --- core/src/main/java/util/Registry.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/src/main/java/util/Registry.java b/core/src/main/java/util/Registry.java index 0916d959..6f82d7de 100644 --- a/core/src/main/java/util/Registry.java +++ b/core/src/main/java/util/Registry.java @@ -30,7 +30,7 @@ public interface Registry public static final String SHARED_INT_JOKER_VALUE = "jokerValue"; public static final String SHARED_INT_JOKER_QUANTITY = "jokerQuantity"; public static final String SHARED_INT_NUMBER_OF_CARDS = "numberOfCards"; - + //replay public static final String REPLAY_STRING_OPPONENT_THREE_HAND = "opponentThreeHand"; public static final String REPLAY_STRING_OPPONENT_TWO_HAND = "opponentTwoHand"; @@ -139,7 +139,4 @@ public interface Registry public static final String SAVED_GAME_INT_OPPONENT_ONE_NUMBER_OF_CARDS = "opponentOneNumberOfCards"; public static final String SAVED_GAME_INT_PLAYER_NUMBER_OF_CARDS = "playerNumberOfCards"; public static final String SAVED_GAME_STRING_GAME_MODE = "gameMode"; - - //statics for default values etc - public static final String BACK_CODE_CLASSIC_BLUE = "backBlue"; } \ No newline at end of file From 04352bbdf468d33dd613a34372429af7eecb04d1 Mon Sep 17 00:00:00 2001 From: alyssa Date: Wed, 3 Sep 2025 08:55:34 +0100 Subject: [PATCH 09/13] wip tests --- client/build.gradle.kts | 7 ++++ client/src/main/java/screen/MainScreen.java | 5 --- .../main/kotlin/bean/BidListCellRenderer.kt | 15 +++----- .../kotlin/screen/achievement/RewardStar.kt | 3 ++ .../kotlin/bean/BidListCellRendererTest.kt | 38 +++++++++++++++++++ .../src/test/kotlin/game/RenderingUtilTest.kt | 25 ++++++++++++ .../screen/achievement/RewardStarTest.kt | 13 +++++++ 7 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 client/src/test/kotlin/bean/BidListCellRendererTest.kt create mode 100644 client/src/test/kotlin/screen/achievement/RewardStarTest.kt diff --git a/client/build.gradle.kts b/client/build.gradle.kts index 6a3422aa..dfcb09e7 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -39,3 +39,10 @@ tasks.withType { jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED") } + +task("updateScreenshots") { + group = "verification" + useJUnitPlatform() + + jvmArgs = listOf("-DupdateSnapshots=true") +} diff --git a/client/src/main/java/screen/MainScreen.java b/client/src/main/java/screen/MainScreen.java index 2818b652..e1f2696d 100644 --- a/client/src/main/java/screen/MainScreen.java +++ b/client/src/main/java/screen/MainScreen.java @@ -694,11 +694,6 @@ else if (command.equals("bluescreenofdeath")) { AchievementsUtil.unlockBlueScreenOfDeath(); } - else if (command.startsWith("unlock ")) - { - var threshold = command.replace("unlock ", ""); - unlockRewards(Integer.parseInt(threshold)); - } else { textToShow = gamePanel.processCommand(command); diff --git a/client/src/main/kotlin/bean/BidListCellRenderer.kt b/client/src/main/kotlin/bean/BidListCellRenderer.kt index e99e0d54..05f634f3 100644 --- a/client/src/main/kotlin/bean/BidListCellRenderer.kt +++ b/client/src/main/kotlin/bean/BidListCellRenderer.kt @@ -12,7 +12,7 @@ import `object`.Player import util.StringUtil class BidListCellRenderer : DefaultListCellRenderer() { - private var hmNameToColour: MutableMap = HashMap() + private var hmNameToColour: Map = mapOf() override fun getListCellRendererComponent( list: JList<*>?, @@ -28,14 +28,10 @@ class BidListCellRenderer : DefaultListCellRenderer() { } fun updateColours(players: MutableCollection) { - this.hmNameToColour.clear() - - for (player in players) { - hmNameToColour.put(player.name, player.colour) - } + this.hmNameToColour = players.associate { it.name to it.colour } } - fun updateColours(map: MutableMap) { + fun updateColours(map: Map) { this.hmNameToColour = map } @@ -44,10 +40,10 @@ class BidListCellRenderer : DefaultListCellRenderer() { playerName = StringUtil.escapeHtml(playerName) val colour = hmNameToColour.get(playerName) - var playerNamePrefix = playerName + ": " + var playerNamePrefix = "$playerName: " if (action.blind) { - playerNamePrefix = "[" + playerName + "]: " + playerNamePrefix = "[$playerName]: " } var text = "$playerNamePrefix" @@ -62,6 +58,7 @@ class BidListCellRenderer : DefaultListCellRenderer() { // The unicode for a moon doesn't work in HTML. Also shrink to match the size of the other // suits. text = text.replace(MOONS_SYMBOL.toRegex(), "🌙") + text += "" return text } } diff --git a/client/src/main/kotlin/screen/achievement/RewardStar.kt b/client/src/main/kotlin/screen/achievement/RewardStar.kt index 5c6516eb..f1ff4f60 100644 --- a/client/src/main/kotlin/screen/achievement/RewardStar.kt +++ b/client/src/main/kotlin/screen/achievement/RewardStar.kt @@ -1,6 +1,7 @@ package screen.achievement import achievement.Reward +import java.awt.Dimension import java.awt.event.MouseEvent import java.awt.event.MouseListener import javax.swing.JLabel @@ -9,7 +10,9 @@ import util.Images class RewardStar(val hoverDesc: String, val reward: Reward) : JLabel(), MouseListener { init { + preferredSize = Dimension(17, 16) addMouseListener(this) + toggle() } fun toggle() { diff --git a/client/src/test/kotlin/bean/BidListCellRendererTest.kt b/client/src/test/kotlin/bean/BidListCellRendererTest.kt new file mode 100644 index 00000000..969d44a1 --- /dev/null +++ b/client/src/test/kotlin/bean/BidListCellRendererTest.kt @@ -0,0 +1,38 @@ +package bean + +import game.ChallengeAction +import game.IllegalAction +import game.Suit +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test +import testCore.makeEntropyBidAction + +class BidListCellRendererTest { + @Test + fun `HTML rendering - blind challenge`() { + val challenge = ChallengeAction("Alyssa", true) + val result = makeRenderer().toHtmlString(challenge) + result shouldBe "[Alyssa]: Challenge" + } + + @Test + fun `HTML rendering - illegal`() { + val challenge = IllegalAction("Mark", false) + val result = makeRenderer().toHtmlString(challenge) + result shouldBe "Mark: Illegal!" + } + + @Test + fun `HTML rendering - bid with card to show`() { + val bid = makeEntropyBidAction(cardToReveal = "Ac", amount = 2, suit = Suit.Spades) + + val result = makeRenderer().toHtmlString(bid) + result shouldBe + "Alyssa: 2♠&emsp(Shows: Ac)" + } + + private fun makeRenderer() = + BidListCellRenderer().also { + it.updateColours(mapOf("Alyssa" to "red", "Mark" to "blue", "David" to "green")) + } +} diff --git a/client/src/test/kotlin/game/RenderingUtilTest.kt b/client/src/test/kotlin/game/RenderingUtilTest.kt index b684bb59..275149f8 100644 --- a/client/src/test/kotlin/game/RenderingUtilTest.kt +++ b/client/src/test/kotlin/game/RenderingUtilTest.kt @@ -1,8 +1,13 @@ package game import io.kotest.matchers.shouldBe +import java.awt.Color import org.junit.jupiter.api.Test +import preference.FOUR_COLOURS +import preference.PreferenceSetting +import testCore.makeEntropyBidAction import util.AbstractClientTest +import util.ClientGlobals class RenderingUtilTest : AbstractClientTest() { @Test @@ -33,4 +38,24 @@ class RenderingUtilTest : AbstractClientTest() { "2, " + "3)" } + + @Test + fun `HTML rendering for an entropy bid`() { + val bid = makeEntropyBidAction(suit = Suit.Diamonds, amount = 1) + bid.htmlString() shouldBe "1♦" + + ClientGlobals.preferenceStore.save(PreferenceSetting.NumberOfColours, FOUR_COLOURS) + bid.htmlString() shouldBe "1♦" + } + + @Test + fun `Should be able to get a suit colour`() { + Suit.Diamonds.getColour() shouldBe Color.red + Suit.Diamonds.getColourHex() shouldBe "#FF0000FF" + + ClientGlobals.preferenceStore.save(PreferenceSetting.NumberOfColours, FOUR_COLOURS) + + Suit.Diamonds.getColour() shouldBe Color.blue + Suit.Diamonds.getColourHex() shouldBe "#0000FFFF" + } } diff --git a/client/src/test/kotlin/screen/achievement/RewardStarTest.kt b/client/src/test/kotlin/screen/achievement/RewardStarTest.kt new file mode 100644 index 00000000..7c4ee98a --- /dev/null +++ b/client/src/test/kotlin/screen/achievement/RewardStarTest.kt @@ -0,0 +1,13 @@ +package screen.achievement + +import achievement.Reward +import com.github.alyssaburlton.swingtest.shouldMatchImage +import org.junit.jupiter.api.Test + +class RewardStarTest { + @Test + fun `Screenshot - locked`() { + val star = RewardStar("", Reward.NegativeJacks) + star.shouldMatchImage("rewardLocked") + } +} From d14f8eab0122495a7f48fd24669cc30649432311 Mon Sep 17 00:00:00 2001 From: alyssa Date: Wed, 10 Sep 2025 08:38:00 +0100 Subject: [PATCH 10/13] RewardStar tests --- client/build.gradle.kts | 7 --- .../screen/achievement/RewardStarTest.kt | 45 +++++++++++++++++-- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/client/build.gradle.kts b/client/build.gradle.kts index dfcb09e7..6a3422aa 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -39,10 +39,3 @@ tasks.withType { jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED") } - -task("updateScreenshots") { - group = "verification" - useJUnitPlatform() - - jvmArgs = listOf("-DupdateSnapshots=true") -} diff --git a/client/src/test/kotlin/screen/achievement/RewardStarTest.kt b/client/src/test/kotlin/screen/achievement/RewardStarTest.kt index 7c4ee98a..2bf800a5 100644 --- a/client/src/test/kotlin/screen/achievement/RewardStarTest.kt +++ b/client/src/test/kotlin/screen/achievement/RewardStarTest.kt @@ -1,13 +1,52 @@ package screen.achievement import achievement.Reward -import com.github.alyssaburlton.swingtest.shouldMatchImage +import com.github.alyssaburlton.swingtest.doClick +import com.github.alyssaburlton.swingtest.doHover +import com.github.alyssaburlton.swingtest.doHoverAway +import com.github.alyssaburlton.swingtest.findWindow +import io.kotest.matchers.nulls.shouldNotBeNull +import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test +import util.AbstractClientTest +import util.Images -class RewardStarTest { +class RewardStarTest : AbstractClientTest() { @Test fun `Screenshot - locked`() { val star = RewardStar("", Reward.NegativeJacks) - star.shouldMatchImage("rewardLocked") + star.icon shouldBe Images.REWARD_LOCKED + } + + @Test + fun `Screenshot - unlocked`() { + Reward.NegativeJacks.unlock() + + val star = RewardStar("", Reward.NegativeJacks) + star.icon shouldBe Images.REWARD_UNLOCKED + + star.doHover() + star.icon shouldBe Images.REWARD_UNLOCKED_HOVERED + + star.doHoverAway() + star.icon shouldBe Images.REWARD_UNLOCKED + } + + @Test + fun `Should do nothing on click if locked`() { + Reward.NegativeJacks.unlock() + + val star = RewardStar("", Reward.NegativeJacks) + star.doClick(async = true) + + findWindow().shouldNotBeNull() + } + + @Test + fun `Should launch reward dialog on click`() { + val star = RewardStar("", Reward.NegativeJacks) + star.doClick(async = true) + + findWindow() shouldBe null } } From ca35a75dc236e52f4ef9383ff50f1d63810077c9 Mon Sep 17 00:00:00 2001 From: alyssa Date: Wed, 10 Sep 2025 08:43:35 +0100 Subject: [PATCH 11/13] fix up html rendering test --- client/src/test/kotlin/bean/BidListCellRendererTest.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/test/kotlin/bean/BidListCellRendererTest.kt b/client/src/test/kotlin/bean/BidListCellRendererTest.kt index 969d44a1..0a12db73 100644 --- a/client/src/test/kotlin/bean/BidListCellRendererTest.kt +++ b/client/src/test/kotlin/bean/BidListCellRendererTest.kt @@ -6,8 +6,9 @@ import game.Suit import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test import testCore.makeEntropyBidAction +import util.AbstractClientTest -class BidListCellRendererTest { +class BidListCellRendererTest : AbstractClientTest() { @Test fun `HTML rendering - blind challenge`() { val challenge = ChallengeAction("Alyssa", true) @@ -28,7 +29,7 @@ class BidListCellRendererTest { val result = makeRenderer().toHtmlString(bid) result shouldBe - "Alyssa: 2♠&emsp(Shows: Ac)" + "Alyssa: 2♠&emsp(Shows: Ac)" } private fun makeRenderer() = From 1f6e17e50cd28b63438234e03babb0ac74b80934 Mon Sep 17 00:00:00 2001 From: alyssa Date: Thu, 18 Sep 2025 08:46:03 +0100 Subject: [PATCH 12/13] start on preference tests --- .../screen/preference/PreferencesPanelMisc.kt | 1 + .../preference/PreferencesPanelMiscTest.kt | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 client/src/test/kotlin/screen/preference/PreferencesPanelMiscTest.kt diff --git a/client/src/main/kotlin/screen/preference/PreferencesPanelMisc.kt b/client/src/main/kotlin/screen/preference/PreferencesPanelMisc.kt index a8b15c90..37892d82 100644 --- a/client/src/main/kotlin/screen/preference/PreferencesPanelMisc.kt +++ b/client/src/main/kotlin/screen/preference/PreferencesPanelMisc.kt @@ -77,6 +77,7 @@ class PreferencesPanelMisc(parent: PreferencesDialog) : add(lblOtherOptions) separator_3.setBounds(0, 38, 429, 2) add(separator_3) + chosenDirectory.name = "replayDirectory" chosenDirectory.setBounds(116, 67, 180, 22) chosenDirectory.setEditable(false) add(chosenDirectory) diff --git a/client/src/test/kotlin/screen/preference/PreferencesPanelMiscTest.kt b/client/src/test/kotlin/screen/preference/PreferencesPanelMiscTest.kt new file mode 100644 index 00000000..cf3b108f --- /dev/null +++ b/client/src/test/kotlin/screen/preference/PreferencesPanelMiscTest.kt @@ -0,0 +1,74 @@ +package screen.preference + +import com.github.alyssaburlton.swingtest.clickChild +import com.github.alyssaburlton.swingtest.getChild +import com.github.alyssaburlton.swingtest.shouldBeDisabled +import com.github.alyssaburlton.swingtest.shouldBeEnabled +import io.kotest.matchers.shouldBe +import io.mockk.mockk +import javax.swing.JButton +import javax.swing.JCheckBox +import javax.swing.JRadioButton +import javax.swing.JSpinner +import javax.swing.JTextField +import org.junit.jupiter.api.Test +import preference.GAME_SPEED_FAST +import preference.PreferenceSetting +import util.AbstractClientTest +import util.ClientGlobals.preferenceStore + +class PreferencesPanelMiscTest : AbstractClientTest() { + @Test + fun `Should load existing preferences`() { + preferenceStore.save(PreferenceSetting.SaveReplays, true) + preferenceStore.save(PreferenceSetting.AutoSave, true) + preferenceStore.save(PreferenceSetting.ReplayDirectory, "/foo/bar") + preferenceStore.save(PreferenceSetting.OpenReplayOnFirstRound, true) + preferenceStore.save(PreferenceSetting.AutoStartNextRound, true) + preferenceStore.save(PreferenceSetting.AutoStartSeconds, 4) + preferenceStore.save(PreferenceSetting.PopUpRooms, true) + preferenceStore.save(PreferenceSetting.CheckForUpdates, false) + preferenceStore.save(PreferenceSetting.GameSpeed, GAME_SPEED_FAST) + + val panel = PreferencesPanelMisc(mockk(relaxed = true)) + panel.initVariables() + + panel.getChild(text = "Save replays").isSelected shouldBe true + panel.getChild(text = "Autosave on exit").isSelected shouldBe true + panel.getChild("replayDirectory").shouldBeEnabled() + panel.getChild("replayDirectory").text shouldBe "/foo/bar\\Replays" + + panel.getChild(text = "First Round").isSelected shouldBe true + panel.getChild(text = "Last Round").isSelected shouldBe false + panel.getChild(text = "Automatically start next round after").isSelected shouldBe + true + + panel.getChild().value shouldBe 4 + + panel.getChild(text = "Pop up online rooms on my turn").isSelected shouldBe true + panel.getChild(text = "Automatically check for updates").isSelected shouldBe + false + + panel.getChild(text = "Slow").isSelected shouldBe false + panel.getChild(text = "Medium").isSelected shouldBe false + panel.getChild(text = "Fast").isSelected shouldBe true + } + + @Test + fun `Ticking and unticking save replays should toggle related components`() { + val panel = PreferencesPanelMisc(mockk(relaxed = true)) + panel.initVariables() + + panel.getChild(text = "Save replays").isSelected shouldBe false + panel.getChild("replayDirectory").shouldBeDisabled() + panel.getChild(text = "...").shouldBeDisabled() + + panel.clickChild(text = "Save replays") + panel.getChild("replayDirectory").shouldBeEnabled() + panel.getChild(text = "...").shouldBeEnabled() + + panel.clickChild(text = "Save replays") + panel.getChild("replayDirectory").shouldBeDisabled() + panel.getChild(text = "...").shouldBeDisabled() + } +} From f5e0b03ffea3e077f031a5fc6bc5be1add876b78 Mon Sep 17 00:00:00 2001 From: alyssa Date: Sat, 4 Oct 2025 21:20:44 +0100 Subject: [PATCH 13/13] appearance panel tests --- client/src/main/java/bean/ComboBoxItem.java | 43 ----- .../java/object/DisabledComboBoxModel.java | 2 +- client/src/main/kotlin/bean/ComboBoxItem.kt | 6 + .../preference/PreferencesPanelAppearance.kt | 76 +++------ .../src/main/kotlin/utils/SwingUtils.kt | 3 + .../PreferencesPanelAppearanceTest.kt | 158 ++++++++++++++++++ 6 files changed, 192 insertions(+), 96 deletions(-) delete mode 100644 client/src/main/java/bean/ComboBoxItem.java create mode 100644 client/src/main/kotlin/bean/ComboBoxItem.kt rename {core => client}/src/main/kotlin/utils/SwingUtils.kt (89%) create mode 100644 client/src/test/kotlin/screen/preference/PreferencesPanelAppearanceTest.kt diff --git a/client/src/main/java/bean/ComboBoxItem.java b/client/src/main/java/bean/ComboBoxItem.java deleted file mode 100644 index 940b43e8..00000000 --- a/client/src/main/java/bean/ComboBoxItem.java +++ /dev/null @@ -1,43 +0,0 @@ -package bean; - -public class ComboBoxItem -{ - private Object visibleData; - private E hiddenData; - private boolean enabled = true; - - public ComboBoxItem(E hiddenData, Object visibleData) - { - this.hiddenData = hiddenData; - this.visibleData = visibleData; - } - - public Object getVisibleData() - { - return visibleData; - } - public E getHiddenData() - { - return hiddenData; - } - - public boolean isEnabled() - { - return enabled; - } - public void setEnabled(boolean enabled) - { - this.enabled = enabled; - } - - @Override - public String toString() - { - if (enabled) - { - return "" + visibleData; - } - - return "" + visibleData + ""; - } -} diff --git a/client/src/main/java/object/DisabledComboBoxModel.java b/client/src/main/java/object/DisabledComboBoxModel.java index 274bf83a..5df8339a 100644 --- a/client/src/main/java/object/DisabledComboBoxModel.java +++ b/client/src/main/java/object/DisabledComboBoxModel.java @@ -31,7 +31,7 @@ public void setSelectedComboBoxItem(ComboBoxItem comboBoxItem) { if (comboBoxItem != null) { - if (comboBoxItem.isEnabled()) + if (comboBoxItem.getEnabled()) { super.setSelectedItem(comboBoxItem); } diff --git a/client/src/main/kotlin/bean/ComboBoxItem.kt b/client/src/main/kotlin/bean/ComboBoxItem.kt new file mode 100644 index 00000000..ff4bb7ec --- /dev/null +++ b/client/src/main/kotlin/bean/ComboBoxItem.kt @@ -0,0 +1,6 @@ +package bean + +data class ComboBoxItem(val hiddenData: E, val visibleData: String, val enabled: Boolean) { + override fun toString() = + if (enabled) visibleData else "$visibleData" +} diff --git a/client/src/main/kotlin/screen/preference/PreferencesPanelAppearance.kt b/client/src/main/kotlin/screen/preference/PreferencesPanelAppearance.kt index 887f7ee5..bd2ffba5 100644 --- a/client/src/main/kotlin/screen/preference/PreferencesPanelAppearance.kt +++ b/client/src/main/kotlin/screen/preference/PreferencesPanelAppearance.kt @@ -93,6 +93,7 @@ class PreferencesPanelAppearance(parent: PreferencesDialog) : deckDesignPanel.setLayout(null) rdbtnClassicDesign.setBounds(6, 30, 72, 23) deckDesignPanel.add(rdbtnClassicDesign) + rdbtnMinimalistDesign.name = "MinimalistDesignRadio" rdbtnMinimalistDesign.setBounds(80, 30, 146, 23) deckDesignPanel.add(rdbtnMinimalistDesign) deckDesignPanel.add(lblCardDesign) @@ -122,6 +123,7 @@ class PreferencesPanelAppearance(parent: PreferencesDialog) : add(jokerDesignPanel) rdbtnClassicJokers.setBounds(6, 30, 72, 23) jokerDesignPanel.add(rdbtnClassicJokers) + rdbtnDeveloperJokers.name = "DeveloperJokersRadio" rdbtnDeveloperJokers.setBounds(80, 30, 102, 23) jokerDesignPanel.add(rdbtnDeveloperJokers) separator_1.setBounds(0, 38, 429, 2) @@ -141,6 +143,7 @@ class PreferencesPanelAppearance(parent: PreferencesDialog) : jokerPreviewPanel.add(labelJo1) labelJo3.setBounds(259, 20, 72, 96) jokerPreviewPanel.add(labelJo3) + cbFourColour.name = "FourColourCheckbox" cbFourColour.setBounds(17, 48, 135, 23) add(cbFourColour) backDesignPanel.setLayout(null) @@ -151,8 +154,10 @@ class PreferencesPanelAppearance(parent: PreferencesDialog) : lblCardBacks.setFont(Font("Tahoma", Font.BOLD, 14)) lblCardBacks.setBounds(127, 8, 102, 17) backDesignPanel.add(lblCardBacks) + labelBack.name = "BackPreview" labelBack.setBounds(23, 9, 72, 96) backDesignPanel.add(labelBack) + comboBoxBacks.name = "backs" comboBoxBacks.setBounds(121, 46, 190, 22) backDesignPanel.add(comboBoxBacks) panelLookAndFeel.setLayout(null) @@ -260,52 +265,36 @@ class PreferencesPanelAppearance(parent: PreferencesDialog) : val model: ComboBoxModel> = DisabledComboBoxModel(backs) comboBoxBacks.setModel(model) - var selectedItem = getSelectedItemForCode(backs, cardBacks) - if (selectedItem == null) { - selectedItem = ComboBoxItem("backBlue", "Blue") - } - + val selectedItem = backs.firstOrNull { it.hiddenData == cardBacks } ?: backs.firstElement() comboBoxBacks.setSelectedItem(selectedItem) } private fun initialiseBacksVector(): Vector> { val backs = Vector>() - backs.addElement(ComboBoxItem("backBlue", "Blue")) - backs.addElement(ComboBoxItem("backRed", "Red")) + backs.addElement(ComboBoxItem("backBlue", "Blue", true)) + backs.addElement(ComboBoxItem("backRed", "Red", true)) - addIfUnlocked(backs, ComboBoxItem("backGreen", "Green"), Reward.FourColours) - addIfUnlocked(backs, ComboBoxItem("backPurple", "Purple"), Reward.NegativeJacks) - addIfUnlocked(backs, ComboBoxItem("backOrange", "Orange"), Reward.Blind) - addIfUnlocked( - backs, - ComboBoxItem("backLightBlue", "Light Blue"), - Reward.MinimalistDeck, - ) - addIfUnlocked(backs, ComboBoxItem("backPink", "Pink"), Reward.Vectropy) - addIfUnlocked(backs, ComboBoxItem("backSilver", "Silver"), Reward.CardReveal) - addIfUnlocked(backs, ComboBoxItem("backGold", "Gold"), Reward.ExtraSuits) - addIfUnlocked(backs, ComboBoxItem("backMatrix", "Matrix"), Reward.Illegal) - addIfUnlocked(backs, ComboBoxItem("backCosmic", "Cosmic"), Reward.DeveloperSet) - addIfUnlocked(backs, ComboBoxItem("backRainbow", "Rainbow"), Reward.Cheats) + backs.addElement(makeComboBoxItem("backGreen", "Green", Reward.FourColours)) + backs.addElement(makeComboBoxItem("backPurple", "Purple", Reward.NegativeJacks)) + backs.addElement(makeComboBoxItem("backOrange", "Orange", Reward.Blind)) + backs.addElement(makeComboBoxItem("backLightBlue", "Light Blue", Reward.MinimalistDeck)) + backs.addElement(makeComboBoxItem("backPink", "Pink", Reward.Vectropy)) + backs.addElement(makeComboBoxItem("backSilver", "Silver", Reward.CardReveal)) + backs.addElement(makeComboBoxItem("backGold", "Gold", Reward.ExtraSuits)) + backs.addElement(makeComboBoxItem("backMatrix", "Matrix", Reward.Illegal)) + backs.addElement(makeComboBoxItem("backCosmic", "Cosmic", Reward.DeveloperSet)) + backs.addElement(makeComboBoxItem("backRainbow", "Rainbow", Reward.Cheats)) return backs } - private fun addIfUnlocked( - backs: Vector>, - item: ComboBoxItem, - reward: Reward, - ) { + private fun makeComboBoxItem(assetName: String, displayName: String, reward: Reward) = if (reward.isUnlocked()) { - backs.addElement(item) + ComboBoxItem(assetName, displayName, true) } else { - val disabledItem = - ComboBoxItem("", reward.threshold.toString() + " achievements to unlock") - disabledItem.isEnabled = false - backs.addElement(disabledItem) + ComboBoxItem("", reward.threshold.toString() + " achievements to unlock", false) } - } private fun setLookAndFeelComboBoxModel() { val backs = Vector() @@ -319,32 +308,15 @@ class PreferencesPanelAppearance(parent: PreferencesDialog) : comboBoxLookAndFeel.setSelectedItem(lookAndFeel) } - private fun getSelectedItemForCode( - backs: Vector>, - code: String?, - ): ComboBoxItem? { - val size = backs.size - for (i in 0..? if (selection == null) { - cardBacks = comboBoxBacks.getItemAt(0)!!.getHiddenData() + cardBacks = comboBoxBacks.getItemAt(0)!!.hiddenData } else { - cardBacks = selection.getHiddenData() + cardBacks = selection.hiddenData } - val back = ImageIcon(javaClass.getResource("/backs/" + cardBacks + ".png")) + val back = ImageIcon(javaClass.getResource("/backs/$cardBacks.png")) labelBack.setIcon(back) } diff --git a/core/src/main/kotlin/utils/SwingUtils.kt b/client/src/main/kotlin/utils/SwingUtils.kt similarity index 89% rename from core/src/main/kotlin/utils/SwingUtils.kt rename to client/src/main/kotlin/utils/SwingUtils.kt index 7d0ef7cc..9c90042e 100644 --- a/core/src/main/kotlin/utils/SwingUtils.kt +++ b/client/src/main/kotlin/utils/SwingUtils.kt @@ -2,6 +2,7 @@ package utils import java.awt.Component import java.awt.Container +import javax.swing.JComboBox /** * Recurses through all child components, returning an ArrayList of all children of the appropriate @@ -32,3 +33,5 @@ fun addComponents(ret: MutableList, components: Array, desired } } } + +fun JComboBox.items() = (0 until itemCount).map { this.getItemAt(it) } diff --git a/client/src/test/kotlin/screen/preference/PreferencesPanelAppearanceTest.kt b/client/src/test/kotlin/screen/preference/PreferencesPanelAppearanceTest.kt new file mode 100644 index 00000000..1b9b1653 --- /dev/null +++ b/client/src/test/kotlin/screen/preference/PreferencesPanelAppearanceTest.kt @@ -0,0 +1,158 @@ +package screen.preference + +import achievement.Reward +import bean.ComboBoxItem +import com.github.alyssaburlton.swingtest.getChild +import com.github.alyssaburlton.swingtest.shouldBeDisabled +import com.github.alyssaburlton.swingtest.shouldBeEnabled +import com.github.alyssaburlton.swingtest.shouldMatch +import io.kotest.matchers.collections.shouldContainExactly +import io.kotest.matchers.shouldBe +import io.mockk.mockk +import javax.swing.ImageIcon +import javax.swing.JCheckBox +import javax.swing.JComboBox +import javax.swing.JLabel +import javax.swing.JRadioButton +import org.junit.jupiter.api.Test +import preference.PreferenceSetting +import util.AbstractClientTest +import util.ClientGlobals.preferenceStore +import utils.items + +class PreferencesPanelAppearanceTest : AbstractClientTest() { + @Test + fun `Should only show unlocked card backs`() { + Reward.FourColours.unlock() + + val panel = openPreferencePanel() + + val comboBox = panel.getChild>("backs") + comboBox + .items() + .shouldContainExactly( + ComboBoxItem("backBlue", "Blue", true), + ComboBoxItem("backRed", "Red", true), + ComboBoxItem("backGreen", "Green", true), + ComboBoxItem("", "10 achievements to unlock", false), + ComboBoxItem("", "15 achievements to unlock", false), + ComboBoxItem("", "20 achievements to unlock", false), + ComboBoxItem("", "25 achievements to unlock", false), + ComboBoxItem("", "30 achievements to unlock", false), + ComboBoxItem("", "35 achievements to unlock", false), + ComboBoxItem("", "40 achievements to unlock", false), + ComboBoxItem("", "45 achievements to unlock", false), + ComboBoxItem("", "50 achievements to unlock", false), + ) + + // Can't select a disabled entry + comboBox.selectedIndex = 3 + comboBox.selectedIndex shouldBe 0 + + // Can select an enabled entry + comboBox.selectedIndex = 2 + comboBox.selectedIndex shouldBe 2 + } + + @Test + fun `Backs combo box should update preview and saved preference`() { + Reward.FourColours.unlock() + val panel = openPreferencePanel() + val comboBox = panel.getChild>("backs") + + comboBox.selectedIndex = 1 + panel.backPreviewIcon().shouldMatch(ImageIcon(javaClass.getResource("/backs/backRed.png"))) + + comboBox.selectedIndex = 2 + panel + .backPreviewIcon() + .shouldMatch(ImageIcon(javaClass.getResource("/backs/backGreen.png"))) + + panel.savePreferences() + preferenceStore.get(PreferenceSetting.CardBacks) shouldBe "backGreen" + } + + @Test + fun `Backs combo box should load correct selection from preference`() { + preferenceStore.save(PreferenceSetting.CardBacks, "backRed") + + val panel = openPreferencePanel() + val comboBox = panel.getChild>("backs") + + comboBox.selectedItem shouldBe ComboBoxItem("backRed", "Red", true) + } + + @Test + fun `Backs combo box should revert to Blue if value stored in preference is no longer unlocked (eg due to wiped data)`() { + preferenceStore.save(PreferenceSetting.CardBacks, "backGreen") + + val panel = openPreferencePanel() + val comboBox = panel.getChild>("backs") + + comboBox.selectedItem shouldBe ComboBoxItem("backBlue", "Blue", true) + } + + @Test + fun `4 colour checkbox should be locked or unlocked as appropriate`() { + val panel = openPreferencePanel() + + val checkbox = panel.getChild("FourColourCheckbox") + checkbox.shouldBeDisabled() + checkbox.isSelected shouldBe false + checkbox.text shouldBe "Locked" + checkbox.toolTipText shouldBe "Unlock at 5 achievements" + + Reward.FourColours.unlock() + val panel2 = openPreferencePanel() + val checkbox2 = panel2.getChild("FourColourCheckbox") + + checkbox2.shouldBeEnabled() + checkbox2.text shouldBe "Use 4 colour deck" + checkbox2.toolTipText shouldBe null + } + + @Test + fun `Minimalist deck design radio button should be locked or unlocked as appropriate`() { + val panel = openPreferencePanel() + + val rdbtn = panel.getChild("MinimalistDesignRadio") + rdbtn.shouldBeDisabled() + rdbtn.isSelected shouldBe false + rdbtn.text shouldBe "Locked" + rdbtn.toolTipText shouldBe "Unlock at 20 achievements" + + Reward.MinimalistDeck.unlock() + val panel2 = openPreferencePanel() + val rdbtn2 = panel2.getChild("MinimalistDesignRadio") + + rdbtn2.shouldBeEnabled() + rdbtn2.text shouldBe "Minimalist" + rdbtn2.toolTipText shouldBe null + } + + @Test + fun `Developer jokers design radio button should be locked or unlocked as appropriate`() { + val panel = openPreferencePanel() + + val rdbtn = panel.getChild("DeveloperJokersRadio") + rdbtn.shouldBeDisabled() + rdbtn.isSelected shouldBe false + rdbtn.text shouldBe "Locked" + rdbtn.toolTipText shouldBe "Unlock at 45 achievements" + + Reward.DeveloperSet.unlock() + val panel2 = openPreferencePanel() + val rdbtn2 = panel2.getChild("DeveloperJokersRadio") + + rdbtn2.shouldBeEnabled() + rdbtn2.text shouldBe "Developers" + rdbtn2.toolTipText shouldBe null + } + + private fun PreferencesPanelAppearance.backPreviewIcon(): ImageIcon = + getChild("BackPreview").icon as ImageIcon + + private fun openPreferencePanel(): PreferencesPanelAppearance { + return PreferencesPanelAppearance(mockk(relaxed = true)).also { it.initVariables() } + } +}