Huge update to the GUI codebase.

- Make match screen in gui-desktop non-singleton, allowing multiple games to be played simultaneously.
- Separate global gui commands (IGuiBase) from game-specific gui commands (IGuiGame), allowing games to send their commands to the correct gui.
This commit is contained in:
elcnesh
2015-02-17 08:47:55 +00:00
parent 4ac5d67a02
commit 4a38b0d817
244 changed files with 5532 additions and 3554 deletions

16
.gitattributes vendored
View File

@@ -514,6 +514,7 @@ forge-game/src/main/java/forge/game/cost/CostUntapType.java -text
forge-game/src/main/java/forge/game/cost/ICostVisitor.java -text
forge-game/src/main/java/forge/game/cost/PaymentDecision.java -text
forge-game/src/main/java/forge/game/cost/package-info.java svneol=native#text/plain
forge-game/src/main/java/forge/game/event/Event.java -text
forge-game/src/main/java/forge/game/event/EventValueChangeType.java -text
forge-game/src/main/java/forge/game/event/GameEvent.java -text
forge-game/src/main/java/forge/game/event/GameEventAnteCardsSelected.java -text
@@ -1009,6 +1010,7 @@ forge-gui-desktop/src/main/java/forge/screens/match/controllers/CAntes.java -tex
forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java -text
forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCommand.java -text
forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetail.java -text
forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java -text
forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDev.java -text
forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDock.java -text
forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java -text
@@ -1099,7 +1101,6 @@ forge-gui-desktop/src/main/java/forge/toolbox/special/PhaseLabel.java -text
forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java -text
forge-gui-desktop/src/main/java/forge/toolbox/special/package-info.java -text
forge-gui-desktop/src/main/java/forge/util/AwtUtil.java -text
forge-gui-desktop/src/main/java/forge/view/ButtonUtil.java -text
forge-gui-desktop/src/main/java/forge/view/FDialog.java -text
forge-gui-desktop/src/main/java/forge/view/FFrame.java -text
forge-gui-desktop/src/main/java/forge/view/FNavigationBar.java -text
@@ -17343,6 +17344,7 @@ forge-gui/src/main/java/forge/card/CardDetailUtil.java -text
forge-gui/src/main/java/forge/card/CardPreferences.java -text
forge-gui/src/main/java/forge/card/CardReaderExperiments.java -text
forge-gui/src/main/java/forge/card/CardScriptInfo.java -text
forge-gui/src/main/java/forge/card/CardScriptParser.java -text
forge-gui/src/main/java/forge/control/ChatArea.java -text
forge-gui/src/main/java/forge/control/FControlGameEventHandler.java -text
forge-gui/src/main/java/forge/control/FControlGamePlayback.java -text
@@ -17370,6 +17372,7 @@ forge-gui/src/main/java/forge/events/IUiEventVisitor.java -text
forge-gui/src/main/java/forge/events/UiEvent.java -text
forge-gui/src/main/java/forge/events/UiEventAttackerDeclared.java -text
forge-gui/src/main/java/forge/events/UiEventBlockerAssigned.java -text
forge-gui/src/main/java/forge/events/UiEventNextGameDecision.java -text
forge-gui/src/main/java/forge/gauntlet/GauntletData.java -text
forge-gui/src/main/java/forge/gauntlet/GauntletIO.java -text
forge-gui/src/main/java/forge/gauntlet/GauntletUtil.java -text
@@ -17377,9 +17380,13 @@ forge-gui/src/main/java/forge/gauntlet/GauntletWinLoseController.java -text
forge-gui/src/main/java/forge/interfaces/IButton.java -text
forge-gui/src/main/java/forge/interfaces/ICheckBox.java -text
forge-gui/src/main/java/forge/interfaces/IComboBox.java -text
forge-gui/src/main/java/forge/interfaces/IDevModeCheats.java -text
forge-gui/src/main/java/forge/interfaces/IDeviceAdapter.java -text
forge-gui/src/main/java/forge/interfaces/IGameController.java -text
forge-gui/src/main/java/forge/interfaces/IGuiBase.java -text
forge-gui/src/main/java/forge/interfaces/IGuiGame.java -text
forge-gui/src/main/java/forge/interfaces/IGuiTimer.java -text
forge-gui/src/main/java/forge/interfaces/IMayViewCards.java -text
forge-gui/src/main/java/forge/interfaces/IProgressBar.java -text
forge-gui/src/main/java/forge/interfaces/ITextField.java -text
forge-gui/src/main/java/forge/interfaces/IWinLoseView.java -text
@@ -17414,10 +17421,10 @@ forge-gui/src/main/java/forge/limited/SealedDeckBuilder.java svneol=native#text/
forge-gui/src/main/java/forge/limited/WinstonDraft.java -text
forge-gui/src/main/java/forge/limited/WinstonDraftAI.java -text
forge-gui/src/main/java/forge/limited/package-info.java svneol=native#text/plain
forge-gui/src/main/java/forge/match/IMatchController.java -text
forge-gui/src/main/java/forge/match/AbstractGuiGame.java -text
forge-gui/src/main/java/forge/match/HostedMatch.java -text
forge-gui/src/main/java/forge/match/MatchConstants.java -text
forge-gui/src/main/java/forge/match/MatchUtil.java -text
forge-gui/src/main/java/forge/match/input/ButtonUtil.java -text
forge-gui/src/main/java/forge/match/NextGameDecision.java -text
forge-gui/src/main/java/forge/match/input/Input.java -text
forge-gui/src/main/java/forge/match/input/InputAttack.java -text
forge-gui/src/main/java/forge/match/input/InputBase.java -text
@@ -17547,7 +17554,6 @@ forge-gui/src/main/java/forge/util/WaitCallback.java -text
forge-gui/src/main/java/forge/util/WaitRunnable.java -text
forge-gui/src/main/java/forge/util/XmlUtil.java -text
forge-gui/src/main/java/forge/util/gui/SGuiChoose.java -text
forge-gui/src/main/java/forge/util/gui/SGuiDialog.java -text
forge-gui/src/main/java/forge/util/gui/SOptionPane.java -text
forge-gui/src/main/java/forge/util/package-info.java -text
forge-gui/src/main/resources/proxy-template.ftl -text

View File

@@ -854,4 +854,8 @@ public class PlayerControllerAi extends PlayerController {
getAi().getCardMemory().clearAllRemembered();
}
@Override
public void autoPassCancel() {
// Do nothing
}
}

View File

@@ -55,7 +55,7 @@ public class GameCopier {
newPlayers.add(clonePlayer(p));
}
GameRules currentRules = origGame.getRules();
Match newMatch = new Match(currentRules, newPlayers);
Match newMatch = new Match(currentRules, newPlayers, origGame.getView().getTitle());
Game newGame = new Game(newPlayers, currentRules, newMatch);
for (int i = 0; i < origGame.getPlayers().size(); i++) {
Player origPlayer = origGame.getPlayers().get(i);

View File

@@ -22,7 +22,7 @@ import forge.util.BinaryUtil;
/**
* The Class CardManaCostShard.
*/
public enum ManaCostShard implements Comparable<ManaCostShard> {
public enum ManaCostShard {
// declaration order matters! Place the shards that offer least ways to be paid for first
/* Pure colors */

View File

@@ -44,7 +44,7 @@ import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.card.CardView;
import forge.game.combat.Combat;
import forge.game.event.GameEvent;
import forge.game.event.Event;
import forge.game.event.GameEventGameOutcome;
import forge.game.phase.Phase;
import forge.game.phase.PhaseHandler;
@@ -101,7 +101,6 @@ public class Game {
private final Match match;
private GameStage age = GameStage.BeforeMulligan;
private GameOutcome outcome;
private boolean disableAutoYields;
private final GameView view;
private final Tracker tracker = new Tracker();
@@ -537,14 +536,10 @@ public class Game {
* Fire only the events after they became real for gamestate and won't get replaced.<br>
* The events are sent to UI, log and sound system. Network listeners are under development.
*/
public void fireEvent(GameEvent event) {
// if (LOG_EVENTS) {
// System.out.println("GE: " + event.toString() + " \t\t " + FThreads.debugGetStackTraceItem(4, true));
// }
public void fireEvent(final Event event) {
events.post(event);
}
public void subscribeToEvents(Object subscriber) {
public void subscribeToEvents(final Object subscriber) {
events.register(subscriber);
}
@@ -605,13 +600,6 @@ public class Game {
return ++hiddenCardIdCounter;
}
public boolean getDisableAutoYields() {
return disableAutoYields;
}
public void setDisableAutoYields(boolean b0) {
disableAutoYields = b0;
}
public Multimap<Player, Card> chooseCardsForAnte(final boolean matchRarity) {
Multimap<Player, Card> anteed = ArrayListMultimap.create();

View File

@@ -25,4 +25,5 @@ public enum GameLogEntryType {
public String getCaption() {
return caption;
}
}

View File

@@ -8,7 +8,6 @@ import forge.deck.DeckFormat;
import forge.deck.DeckSection;
import forge.game.player.RegisteredPlayer;
public enum GameType {
Sealed (DeckFormat.Limited, true, true, true, "Sealed", ""),
Draft (DeckFormat.Limited, true, true, true, "Draft", ""),
@@ -21,9 +20,9 @@ public enum GameType {
Vanguard (DeckFormat.Vanguard, true, true, true, "Vanguard", "Each player has a special \"Avatar\" card that affects the game."),
Commander (DeckFormat.Commander, false, false, false, "Commander", "Each player has a legendary \"General\" card which can be cast at any time and determines deck colors."),
TinyLeaders (DeckFormat.TinyLeaders, false, false, false, "Tiny Leaders", "Each player has a legendary \"General\" card which can be cast at any time and determines deck colors. Each card must have CMC less than 4."),
Planechase (DeckFormat.Planechase, false, false, true, "Planechase", "Plane cards apply global effects. Plane card changed when a player rolls \"Chaos\" on the planar die."),
Archenemy (DeckFormat.Archenemy, false, false, true, "Archenemy", "One player is the Archenemy and can play scheme cards."),
ArchenemyRumble (DeckFormat.Archenemy, false, false, true, "Archenemy Rumble", "All players are Archenemies and can play scheme cards."),
Planechase (DeckFormat.Planechase, false, false, true, "Planechase", "Plane cards apply global effects. The Plane card changes when a player rolls \"Planeswalk\" on the planar die."),
Archenemy (DeckFormat.Archenemy, false, false, true, "Archenemy", "One player is the Archenemy and fights the other players by playing Scheme cards."),
ArchenemyRumble (DeckFormat.Archenemy, false, false, true, "Archenemy Rumble", "All players are Archenemies and can play Scheme cards."),
MomirBasic (DeckFormat.Constructed, false, false, false, "Momir Basic", "Each player has a deck containing 60 basic lands and the Momir Vig avatar.", new Function<RegisteredPlayer, Deck>() {
@Override
public Deck apply(RegisteredPlayer player) {

View File

@@ -22,11 +22,6 @@ import forge.trackable.TrackableProperty;
import forge.util.FCollectionView;
public class GameView extends TrackableObject {
private static GameView currentGame;
public static GameView getCurrentGame() {
return currentGame;
}
/*private final TrackableIndex<CardView> cards = new TrackableIndex<CardView>();
private final TrackableIndex<PlayerView> players = new TrackableIndex<PlayerView>();
@@ -38,8 +33,8 @@ public class GameView extends TrackableObject {
public GameView(final Game game0) {
super(-1, game0.getTracker()); //ID not needed
currentGame = this;
game = game0;
set(TrackableProperty.Title, game.getMatch().getTitle());
set(TrackableProperty.WinningTeam, -1);
GameRules rules = game.getRules();
@@ -58,6 +53,9 @@ public class GameView extends TrackableObject {
return players;
}
public String getTitle() {
return get(TrackableProperty.Title);
}
public boolean isCommander() {
return get(TrackableProperty.Commander);
}
@@ -117,9 +115,6 @@ public class GameView extends TrackableObject {
set(TrackableProperty.GameOver, game.isGameOver());
set(TrackableProperty.MatchOver, game.getMatch().isMatchOver());
set(TrackableProperty.WinningTeam, game.getOutcome() == null ? -1 : game.getOutcome().getWinningTeam());
if (game.isGameOver()) {
currentGame = null;
}
}
public GameLog getGameLog() {
@@ -199,9 +194,9 @@ public class GameView extends TrackableObject {
return game.getMatch().getGamesWonBy(questPlayer);
}
public Deck getDeck(LobbyPlayer guiPlayer) {
for (Player p : game.getRegisteredPlayers()) {
if (p.getLobbyPlayer().equals(guiPlayer)) {
public Deck getDeck(final String lobbyPlayerName) {
for (final Player p : game.getRegisteredPlayers()) {
if (p.getLobbyPlayer().getName().equals(lobbyPlayerName)) {
return p.getRegisteredPlayer().getDeck();
}
}

View File

@@ -1,6 +1,21 @@
package forge.game;
import com.google.common.collect.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import forge.LobbyPlayer;
import forge.deck.CardPool;
@@ -19,25 +34,35 @@ import forge.item.PaperCard;
import forge.util.FCollectionView;
import forge.util.MyRandom;
import java.util.*;
import java.util.Map.Entry;
public class Match {
private final List<RegisteredPlayer> players;
private final GameRules rules;
private final String title;
private final List<GameOutcome> gamesPlayed = new ArrayList<GameOutcome>();
private final List<GameOutcome> gamesPlayedRo;
public Match(GameRules rules0, List<RegisteredPlayer> players0) {
public Match(final GameRules rules0, final List<RegisteredPlayer> players0, final String title) {
gamesPlayedRo = Collections.unmodifiableList(gamesPlayed);
players = Collections.unmodifiableList(Lists.newArrayList(players0));
rules = rules0;
this.title = title;
}
public GameRules getRules() {
return rules;
}
String getTitle() {
final Multiset<RegisteredPlayer> wins = getGamesWon();
final StringBuilder titleAppend = new StringBuilder(title);
titleAppend.append(" (");
for (final RegisteredPlayer rp : players) {
titleAppend.append(wins.count(rp)).append('-');
}
titleAppend.deleteCharAt(titleAppend.length() - 1);
titleAppend.append(')');
return titleAppend.toString();
}
public final List<GameOutcome> getPlayedGames() {
return gamesPlayedRo;
@@ -124,6 +149,13 @@ public class Match {
}
return sum;
}
public Multiset<RegisteredPlayer> getGamesWon() {
final Multiset<RegisteredPlayer> won = HashMultiset.create(players.size());
for (final GameOutcome go : gamesPlayedRo) {
won.add(go.getWinningPlayer().getRegisteredPlayer());
}
return won;
}
public boolean isWonBy(LobbyPlayer questPlayer) {
return getGamesWonBy(questPlayer) >= rules.getGamesToWinMatch();

View File

@@ -103,7 +103,7 @@ public final class AbilityFactory {
AbilityRecordType type = AbilityRecordType.getRecordType(mapParams);
if (null == type) {
String source = hostCard.getName().isEmpty() ? abString : hostCard.getName();
throw new RuntimeException("AbilityFactory : getAbility -- no API in " + source);
throw new RuntimeException("AbilityFactory : getAbility -- no API in " + source + ": " + abString);
}
return getAbility(mapParams, type, hostCard);
}

View File

@@ -17,6 +17,18 @@
*/
package forge.game.card;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
@@ -32,18 +44,15 @@ import forge.card.mana.ManaCostShard;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.GameLogEntryType;
import forge.game.GameView;
import forge.game.ability.AbilityFactory;
import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType;
import forge.game.card.CardCollectionView;
import forge.game.card.CardPredicates.Presets;
import forge.game.cost.Cost;
import forge.game.cost.CostPayment;
import forge.game.event.GameEventCardStatsChanged;
import forge.game.phase.PhaseHandler;
import forge.game.player.Player;
import forge.game.player.PlayerView;
import forge.game.replacement.ReplacementEffect;
import forge.game.replacement.ReplacementHandler;
import forge.game.replacement.ReplacementLayer;
@@ -65,11 +74,6 @@ import forge.util.Aggregates;
import forge.util.FCollectionView;
import forge.util.Lang;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
import java.util.Map.Entry;
/**
* <p>
* CardFactoryUtil class.
@@ -2081,28 +2085,6 @@ public class CardFactoryUtil {
}
*/
public static final String getCommanderInfo(final PlayerView originPlayer) {
GameView game = GameView.getCurrentGame();
if (game == null) { return ""; }
StringBuilder sb = new StringBuilder();
for (PlayerView p : game.getPlayers()) {
final String text;
if (p.equals(originPlayer)) {
text = "Commander Damage from own Commander: ";
}
else {
text = "Commander Damage to " + p.getName() + ": ";
}
int damage = p.getCommanderDamage(originPlayer.getCommander());
if (damage > 0) {
sb.append(text + damage + "\r\n");
}
}
return sb.toString();
}
/**
* <p>
* postFactoryKeywords.
@@ -3366,7 +3348,7 @@ public class CardFactoryUtil {
final String parse = card.getKeywords().get(n);
final String[] k = parse.split(":");
final int num = Integer.parseInt(k[1]);
UUID triggerSvar = UUID.randomUUID();
final String triggerSvar = "DBRipple";
final String actualTrigger = "Mode$ SpellCast | ValidCard$ Card.Self | " +
"Execute$ " + triggerSvar + " | Secondary$ True | TriggerDescription$" +

View File

@@ -531,13 +531,13 @@ public class CardView extends GameEntityView {
}
}
String rulesText = state.getRulesText();
final String rulesText = state.getRulesText();
if (!rulesText.isEmpty()) {
sb.append(rulesText).append("\r\n\r\n");
}
if (isCommander()) {
sb.append(getOwner()).append("'s Commander\r\n");
sb.append(CardFactoryUtil.getCommanderInfo(getOwner())).append("\r\n");
sb.append(getOwner().getCommanderInfo()).append("\r\n");
}
if (isSplitCard()) {

View File

@@ -0,0 +1,5 @@
package forge.game.event;
public abstract class Event {
}

View File

@@ -1,6 +1,6 @@
package forge.game.event;
public abstract class GameEvent {
public abstract class GameEvent extends Event {
public abstract <T> T visit(IGameEventVisitor<T> visitor);
}

View File

@@ -1,9 +1,16 @@
package forge.game.player;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import forge.LobbyPlayer;
import forge.card.ColorSet;
@@ -25,7 +32,6 @@ import forge.game.cost.Cost;
import forge.game.cost.CostPart;
import forge.game.cost.CostPartMana;
import forge.game.mana.Mana;
import forge.game.phase.PhaseType;
import forge.game.replacement.ReplacementEffect;
import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
@@ -38,15 +44,6 @@ import forge.item.PaperCard;
import forge.util.FCollectionView;
import forge.util.ITriggerEvent;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A prototype for player controller class
*
@@ -75,7 +72,6 @@ public abstract class PlayerController {
protected final Game game;
private PhaseType autoPassUntilPhase = null;
protected final Player player;
protected final LobbyPlayer lobbyPlayer;
@@ -85,71 +81,10 @@ public abstract class PlayerController {
lobbyPlayer = lp;
}
/**
* Automatically pass priority until reaching the Cleanup phase of the
* current turn.
*/
public void autoPassUntilEndOfTurn() {
autoPassUntilPhase = PhaseType.CLEANUP;
}
protected PhaseType getAutoPassUntilPhase() {
return autoPassUntilPhase;
}
public void autoPassCancel() {
autoPassUntilPhase = null;
}
public boolean mayAutoPass() {
if (autoPassUntilPhase == null) { return false; }
PhaseType currentPhase = game.getPhaseHandler().getPhase();
if (currentPhase.isBefore(autoPassUntilPhase)) {
if (currentPhase == PhaseType.COMBAT_DECLARE_BLOCKERS && game.getPhaseHandler().isPlayerTurn(player)) {
if (!game.getCombat().getAllBlockers().isEmpty()) {
return false; //prevent auto-passing on Declare Blockers phase if it's your turn and your opponent blocks a creature you attacked with
}
}
return true;
}
return false;
}
public boolean isAI() {
return false;
}
// Abilities to auto-yield to
private final Set<String> autoYields = Sets.newHashSet();
public Iterable<String> getAutoYields() {
return autoYields;
}
public boolean shouldAutoYield(final String key) {
return autoYields.contains(key);
}
public void setShouldAutoYield(final String key, final boolean autoYield) {
if (autoYield) {
autoYields.add(key);
}
else {
autoYields.remove(key);
}
}
// Triggers preliminary choice: ask, decline or play
private Map<Integer, Boolean> triggersAlwaysAccept = new HashMap<Integer, Boolean>();
public boolean shouldAlwaysAcceptTrigger(Integer trigger) { return Boolean.TRUE.equals(triggersAlwaysAccept.get(trigger)); }
public boolean shouldAlwaysDeclineTrigger(Integer trigger) { return Boolean.FALSE.equals(triggersAlwaysAccept.get(trigger)); }
public boolean shouldAlwaysAskTrigger(Integer trigger) { return !triggersAlwaysAccept.containsKey(trigger); }
public void setShouldAlwaysAcceptTrigger(Integer trigger) { triggersAlwaysAccept.put(trigger, true); }
public void setShouldAlwaysDeclineTrigger(Integer trigger) { triggersAlwaysAccept.put(trigger, false); }
public void setShouldAlwaysAskTrigger(Integer trigger) { triggersAlwaysAccept.remove(trigger); }
// End of Triggers preliminary choice
public Game getGame() { return game; }
public Player getPlayer() { return player; }
public LobbyPlayer getLobbyPlayer() { return lobbyPlayer; }
@@ -290,6 +225,8 @@ public abstract class PlayerController {
// better to have this odd method than those if playerType comparison in ChangeZone
public abstract Card chooseSingleCardForZoneChange(ZoneType destination, List<ZoneType> origin, SpellAbility sa, CardCollection fetchList, DelayedReveal delayedReveal, String selectPrompt, boolean isOptional, Player decider);
public abstract void autoPassCancel();
public boolean isGuiPlayer() {
return false;
}

View File

@@ -1,9 +1,11 @@
package forge.game.player;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import forge.LobbyPlayer;
@@ -85,6 +87,25 @@ public class PlayerView extends GameEntityView {
return opponents != null && opponents.contains(other);
}
public final String getCommanderInfo() {
final StringBuilder sb = new StringBuilder();
for (final PlayerView p : Iterables.concat(Collections.singleton(this), getOpponents())) {
final String text;
if (p.equals(this)) {
text = "Commander Damage from own Commander: ";
} else {
text = "Commander Damage to " + p.getName() + ": ";
}
final int damage = p.getCommanderDamage(this.getCommander());
if (damage > 0) {
sb.append(text + damage + "\r\n");
}
}
return sb.toString();
}
@Override
public String toString() {
return getName();

View File

@@ -145,17 +145,22 @@ public class TriggerHandler {
}
public static Trigger parseTrigger(final Map<String, String> mapParams, final Card host, final boolean intrinsic) {
Trigger ret = null;
final TriggerType type = TriggerType.smartValueOf(mapParams.get("Mode"));
ret = type.createTrigger(mapParams, host, intrinsic);
final Trigger ret = type.createTrigger(mapParams, host, intrinsic);
String triggerZones = mapParams.get("TriggerZones");
final String triggerZones = mapParams.get("TriggerZones");
if (null != triggerZones) {
ret.setActiveZone(EnumSet.copyOf(ZoneType.listValueOf(triggerZones)));
} else if (type == TriggerType.ChangesZone) {
// Special case, because ChangesZone triggers on cards don't
// specify their TriggerZone
final String origin = mapParams.get("Destination");
if (!"Any".equals(origin)) {
ret.setActiveZone(EnumSet.copyOf(ZoneType.listValueOf(origin)));
}
}
String triggerPhases = mapParams.get("Phase");
final String triggerPhases = mapParams.get("Phase");
if (null != triggerPhases) {
ret.setTriggerPhases(PhaseType.parseRange(triggerPhases));
}

View File

@@ -225,7 +225,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
//cancel auto-pass for all opponents of activating player
//when a new non-triggered ability is put on the stack
if (!sp.isTrigger()) {
for (Player p : activator.getOpponents()) {
for (final Player p : activator.getOpponents()) {
p.getController().autoPassCancel();
}
}

View File

@@ -136,6 +136,7 @@ public enum TrackableProperty {
//Game
GameType(TrackableTypes.EnumType(GameType.class)),
Title(TrackableTypes.StringType),
Turn(TrackableTypes.IntegerType),
WinningTeam(TrackableTypes.IntegerType),
MatchOver(TrackableTypes.BooleanType),

View File

@@ -6,8 +6,10 @@ import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.List;
@@ -22,24 +24,19 @@ import com.google.common.base.Function;
import forge.assets.FSkinProp;
import forge.assets.ISkinImage;
import forge.control.GuiTimer;
import forge.deck.CardPool;
import forge.download.GuiDownloadService;
import forge.download.GuiDownloader;
import forge.error.BugReportDialog;
import forge.game.GameEntity;
import forge.game.GameEntityView;
import forge.game.card.CardView;
import forge.game.player.DelayedReveal;
import forge.game.player.IHasIcon;
import forge.gui.BoxedProductCardListViewer;
import forge.gui.CardListViewer;
import forge.gui.GuiChoose;
import forge.gui.framework.FScreen;
import forge.interfaces.IGuiBase;
import forge.interfaces.IGuiGame;
import forge.interfaces.IGuiTimer;
import forge.item.PaperCard;
import forge.match.HostedMatch;
import forge.model.FModel;
import forge.player.PlayerControllerHuman;
import forge.screens.deckeditor.CDeckEditorUI;
import forge.screens.deckeditor.controllers.CEditorQuestCardShop;
import forge.screens.match.CMatchUI;
@@ -53,9 +50,7 @@ import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinImage;
import forge.util.BuildInfo;
import forge.util.Callback;
import forge.util.FCollectionView;
import forge.util.FileUtil;
import forge.util.gui.SGuiChoose;
public class GuiDesktop implements IGuiBase {
@Override
@@ -153,19 +148,6 @@ public class GuiDesktop implements IGuiBase {
return FOptionPane.showOptionDialog(message, title, icon == null ? null : FSkin.getImage(icon), options, defaultOption);
}
@Override
public int showCardOptionDialog(final CardView card, String message, String title, FSkinProp skinIcon, String[] options, int defaultOption) {
if (card != null) {
FThreads.invokeInEdtAndWait(new Runnable() {
@Override
public void run() {
GuiBase.getInterface().setCard(card);
}
});
}
return showOptionDialog(message, title, skinIcon, options, defaultOption);
}
@Override
public String showInputDialog(String message, String title, FSkinProp icon, String initialInput, String[] inputOptions) {
return FOptionPane.showInputDialog(message, title, icon == null ? null : FSkin.getImage(icon), initialInput, inputOptions);
@@ -182,31 +164,13 @@ public class GuiDesktop implements IGuiBase {
@Override
public <T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
final List<T> sourceChoices, final List<T> destChoices, final CardView referenceCard, final boolean sideboardingMode) {
final List<T> sourceChoices, final List<T> destChoices) {
/*if ((sourceChoices != null && !sourceChoices.isEmpty() && sourceChoices.iterator().next() instanceof GameObject)
|| (destChoices != null && !destChoices.isEmpty() && destChoices.iterator().next() instanceof GameObject)) {
System.err.println("Warning: GameObject passed to GUI! Printing stack trace.");
Thread.dumpStack();
}*/
return GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode);
}
@Override
public List<PaperCard> sideboard(CardPool sideboard, CardPool main) {
return GuiChoose.sideboard(sideboard.toFlatList(), main.toFlatList());
}
@Override
public GameEntityView chooseSingleEntityForEffect(String title, FCollectionView<? extends GameEntity> optionList, DelayedReveal delayedReveal, boolean isOptional, PlayerControllerHuman controller) {
if (delayedReveal != null) {
delayedReveal.reveal(controller); //TODO: Merge this into search dialog
}
controller.tempShow(optionList);
List<GameEntityView> gameEntityViews = GameEntityView.getEntityCollection(optionList);
if (isOptional) {
return SGuiChoose.oneOrNone(title, gameEntityViews);
}
return SGuiChoose.one(title, gameEntityViews);
return GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices);
}
@Override
@@ -232,12 +196,6 @@ public class GuiDesktop implements IGuiBase {
return 0;
}
@Override
public void setCard(final CardView card) {
CMatchUI.SINGLETON_INSTANCE.setCard(card);
}
@Override
public String showFileDialog(String title, String defaultDir) {
final JFileChooser fc = new JFileChooser(defaultDir);
@@ -273,7 +231,7 @@ public class GuiDesktop implements IGuiBase {
}
@Override
public void browseToUrl(String url) throws Exception {
public void browseToUrl(String url) throws IOException, URISyntaxException {
Desktop.getDesktop().browse(new URI(url));
}
@@ -310,8 +268,12 @@ public class GuiDesktop implements IGuiBase {
Singletons.getView().getFrame().validate();
}
public IGuiGame getNewGuiGame() {
return new CMatchUI();
};
@Override
public void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi) {
CMatchUI.SINGLETON_INSTANCE.avatarImages.put(player.getName(), ihi.getIconImageKey());
public HostedMatch hostMatch() {
return new HostedMatch();
}
}

View File

@@ -34,8 +34,8 @@ import com.mortennobel.imagescaling.ResampleOp;
import forge.assets.FSkinProp;
import forge.game.card.CardView;
import forge.game.player.PlayerView;
import forge.item.InventoryItem;
import forge.match.MatchUtil;
import forge.model.FModel;
import forge.properties.ForgeConstants;
import forge.properties.ForgePreferences.FPref;
@@ -83,8 +83,8 @@ public class ImageCache {
* retrieve an image from the cache. returns null if the image is not found in the cache
* and cannot be loaded from disk. pass -1 for width and/or height to avoid resizing in that dimension.
*/
public static BufferedImage getImage(final CardView card, final int width, final int height) {
final String key = MatchUtil.getCardImageKey(card.getCurrentState());
public static BufferedImage getImage(final CardView card, final PlayerView viewer, final int width, final int height) {
final String key = card.getCurrentState().getImageKey(viewer);
return scaleImage(key, width, height, true);
}

View File

@@ -18,6 +18,7 @@
package forge.control;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.ComponentAdapter;
@@ -33,11 +34,12 @@ import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import com.google.common.collect.Lists;
import forge.ImageCache;
import forge.LobbyPlayer;
import forge.Singletons;
import forge.assets.FSkinProp;
import forge.control.KeyboardShortcuts.Shortcut;
import forge.gui.GuiDialog;
import forge.gui.SOverlayUtils;
import forge.gui.framework.FScreen;
@@ -45,7 +47,7 @@ import forge.gui.framework.InvalidLayoutFileException;
import forge.gui.framework.SLayoutIO;
import forge.gui.framework.SOverflowUtil;
import forge.gui.framework.SResizingUtil;
import forge.match.MatchUtil;
import forge.match.HostedMatch;
import forge.menus.ForgeMenu;
import forge.model.FModel;
import forge.player.GamePlayerUtil;
@@ -55,7 +57,6 @@ import forge.properties.ForgePreferences.FPref;
import forge.quest.data.QuestPreferences.QPref;
import forge.quest.io.QuestDataIO;
import forge.screens.deckeditor.CDeckEditorUI;
import forge.screens.match.CMatchUI;
import forge.toolbox.FOptionPane;
import forge.toolbox.FSkin;
import forge.view.FFrame;
@@ -73,16 +74,16 @@ public enum FControl implements KeyEventDispatcher {
instance;
private ForgeMenu forgeMenu;
private List<Shortcut> shortcuts;
private JLayeredPane display;
private FScreen currentScreen;
private boolean altKeyLastDown;
private CloseAction closeAction;
private List<HostedMatch> currentMatches = Lists.newArrayList();
public static enum CloseAction {
NONE,
CLOSE_SCREEN,
EXIT_FORGE
EXIT_FORGE;
}
/**
@@ -151,10 +152,10 @@ public enum FControl implements KeyEventDispatcher {
public boolean canExitForge(boolean forRestart) {
String action = (forRestart ? "Restart" : "Exit");
String userPrompt = "Are you sure you wish to " + (forRestart ? "restart" : "exit") + " Forge?";
if (MatchUtil.getGame() != null) {
if (!currentMatches.isEmpty()) {
userPrompt = "A game is currently active. " + userPrompt;
}
if (!FOptionPane.showConfirmDialog(userPrompt, action + " Forge", action, "Cancel", MatchUtil.getGame() == null)) { //default Yes if no game active
if (!FOptionPane.showConfirmDialog(userPrompt, action + " Forge", action, "Cancel", currentMatches.isEmpty())) { //default Yes if no game active
return false;
}
if (!CDeckEditorUI.SINGLETON_INSTANCE.canSwitchAway(true)) {
@@ -174,12 +175,9 @@ public enum FControl implements KeyEventDispatcher {
/** After view and model have been initialized, control can start.*/
public void initialize() {
MatchUtil.setController(CMatchUI.SINGLETON_INSTANCE);
// Preloads skin components (using progress bar).
FSkin.loadFull(true);
shortcuts = KeyboardShortcuts.attachKeyboardShortcuts();
display = FView.SINGLETON_INSTANCE.getLpnDocument();
final ForgePreferences prefs = FModel.getPreferences();
@@ -227,7 +225,7 @@ public enum FControl implements KeyEventDispatcher {
}
private void setGlobalKeyboardHandler() {
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
final KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(this);
}
@@ -245,10 +243,10 @@ public enum FControl implements KeyEventDispatcher {
/**
* Switches between display screens in top level JFrame.
*/
public boolean setCurrentScreen(FScreen screen) {
public boolean setCurrentScreen(final FScreen screen) {
return setCurrentScreen(screen, false);
}
public boolean setCurrentScreen(FScreen screen, boolean previousScreenClosed) {
public boolean setCurrentScreen(final FScreen screen, final boolean previousScreenClosed) {
//TODO: Uncomment the line below if this function stops being used to refresh
//the current screen in some places (such as Continue and Restart in the match screen)
//if (currentScreen == screen) { return; }
@@ -258,8 +256,8 @@ public enum FControl implements KeyEventDispatcher {
return false;
}
if (currentScreen == FScreen.MATCH_SCREEN) { //hide targeting overlay and reset image if was on match screen
SOverlayUtils.hideTargetingOverlay();
if (currentScreen != null && currentScreen.isMatchScreen()) { //hide targeting overlay and reset image if was on match screen
//SOverlayUtils.hideTargetingOverlay();
if (isMatchBackgroundImageVisible()) {
FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon());
}
@@ -272,6 +270,7 @@ public enum FControl implements KeyEventDispatcher {
currentScreen = screen;
//load layout for new current screen
screen.getController().register();
try {
SLayoutIO.loadLayout(null);
} catch (InvalidLayoutFileException ex) {
@@ -281,14 +280,14 @@ public enum FControl implements KeyEventDispatcher {
}
}
screen.getView().populate();
screen.getController().initialize();
screen.getView().populate();
if (screen == FScreen.MATCH_SCREEN) {
if (screen.isMatchScreen()) {
if (isMatchBackgroundImageVisible()) {
FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(FSkin.getIcon(FSkinProp.BG_MATCH));
}
SOverlayUtils.showTargetingOverlay();
//SOverlayUtils.showTargetingOverlay();
}
Singletons.getView().getNavigationBar().updateSelectedTab();
@@ -305,11 +304,6 @@ public enum FControl implements KeyEventDispatcher {
return setCurrentScreen(screen);
}
/** @return List<Shortcut> A list of attached keyboard shortcut descriptions and properties. */
public List<Shortcut> getShortcuts() {
return shortcuts;
}
/** Remove all children from a specified layer. */
private void clearChildren(final int layer0) {
final Component[] children = FView.SINGLETON_INSTANCE.getLpnDocument().getComponentsInLayer(layer0);
@@ -331,6 +325,10 @@ public enum FControl implements KeyEventDispatcher {
if (children.length != 0) { children[0].setSize(display.getSize()); }
}
public Dimension getDisplaySize() {
return display.getSize();
}
/* (non-Javadoc)
* @see java.awt.KeyEventDispatcher#dispatchKeyEvent(java.awt.event.KeyEvent)
*/

View File

@@ -1,20 +1,5 @@
package forge.control;
import forge.Singletons;
import forge.gui.framework.EDocID;
import forge.gui.framework.FScreen;
import forge.gui.framework.SDisplayUtil;
import forge.match.MatchUtil;
import forge.model.FModel;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
import forge.screens.home.settings.VSubmenuPreferences.KeyboardShortcutField;
import forge.screens.match.controllers.CDock;
import org.apache.commons.lang3.StringUtils;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
@@ -22,6 +7,24 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import org.apache.commons.lang3.StringUtils;
import forge.Singletons;
import forge.gui.framework.EDocID;
import forge.gui.framework.SDisplayUtil;
import forge.model.FModel;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
import forge.screens.home.settings.VSubmenuPreferences.KeyboardShortcutField;
import forge.screens.match.CMatchUI;
/**
* Consolidates keyboard shortcut assembly into one location
* for all shortcuts in the project.
@@ -30,6 +33,11 @@ import java.util.List;
* and you're done.
*/
public class KeyboardShortcuts {
public static List<Shortcut> getKeyboardShortcuts() {
return attachKeyboardShortcuts(null);
}
/**
* Attaches all keyboard shortcuts for match UI,
* and returns a list of shortcuts with necessary properties for later access.
@@ -37,19 +45,19 @@ public class KeyboardShortcuts {
* @return List<Shortcut> Shortcut objects
*/
@SuppressWarnings("serial")
public static List<Shortcut> attachKeyboardShortcuts() {
public static List<Shortcut> attachKeyboardShortcuts(final CMatchUI matchUI) {
final JComponent c = Singletons.getView().getFrame().getLayeredPane();
final InputMap im = c.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
final ActionMap am = c.getActionMap();
List<Shortcut> list = new ArrayList<Shortcut>();
final List<Shortcut> list = new ArrayList<Shortcut>();
//========== Match Shortcuts
/** Show stack. */
final Action actShowStack = new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; }
if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; }
SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
}
};
@@ -58,7 +66,7 @@ public class KeyboardShortcuts {
final Action actShowCombat = new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; }
if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; }
SDisplayUtil.showTab(EDocID.REPORT_COMBAT.getDoc());
}
};
@@ -67,7 +75,7 @@ public class KeyboardShortcuts {
final Action actShowConsole = new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; }
if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; }
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
}
};
@@ -76,7 +84,7 @@ public class KeyboardShortcuts {
final Action actShowPlayers = new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; }
if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; }
SDisplayUtil.showTab(EDocID.REPORT_PLAYERS.getDoc());
}
};
@@ -85,7 +93,7 @@ public class KeyboardShortcuts {
final Action actShowDev = new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; }
if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; }
if (ForgePreferences.DEV_MODE) {
SDisplayUtil.showTab(EDocID.DEV_MODE.getDoc());
}
@@ -96,8 +104,9 @@ public class KeyboardShortcuts {
final Action actConcede = new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; }
MatchUtil.concede();
if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; }
if (matchUI == null) { return; }
matchUI.getGameController().concede();
}
};
@@ -105,8 +114,9 @@ public class KeyboardShortcuts {
final Action actEndTurn = new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; }
CDock.SINGLETON_INSTANCE.endTurn();
if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; }
if (matchUI == null) { return; }
matchUI.getGameController().passPriorityUntilEndOfTurn();
}
};
@@ -114,8 +124,9 @@ public class KeyboardShortcuts {
final Action actAllAttack = new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; }
MatchUtil.alphaStrike();
if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; }
if (matchUI == null) { return; }
matchUI.getGameController().alphaStrike();
}
};
@@ -123,8 +134,9 @@ public class KeyboardShortcuts {
final Action actTgtOverlay = new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; }
CDock.SINGLETON_INSTANCE.toggleTargeting();
if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; }
if (matchUI == null) { return; }
matchUI.getCDock().toggleTargeting();
}
};

View File

@@ -21,6 +21,7 @@ import forge.quest.QuestController;
import forge.quest.QuestEvent;
import forge.quest.QuestEventChallenge;
import forge.quest.QuestUtil;
import forge.screens.match.controllers.CDetailPicture;
import forge.toolbox.FLabel;
import forge.toolbox.FOptionPane;
import net.miginfocom.swing.MigLayout;
@@ -42,7 +43,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
private NetDeckCategory netDeckCategory;
private boolean refreshingDeckType;
private final DeckManager lstDecks = new DeckManager(GameType.Constructed);
private final DeckManager lstDecks;
private final FLabel btnViewDeck = new FLabel.ButtonBuilder().text("View Deck").fontSize(14).build();
private final FLabel btnRandom = new FLabel.ButtonBuilder().fontSize(14).build();
@@ -52,9 +53,9 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
private FPref stateSetting = null;
//Show dialog to select a deck
public static Deck promptForDeck(String title, DeckType defaultDeckType, boolean forAi) {
public static Deck promptForDeck(final CDetailPicture cDetailPicture, final String title, final DeckType defaultDeckType, final boolean forAi) {
FThreads.assertExecutedByEdt(true);
final FDeckChooser chooser = new FDeckChooser(forAi);
final FDeckChooser chooser = new FDeckChooser(cDetailPicture, forAi);
chooser.initialize(defaultDeckType);
chooser.populate();
Dimension parentSize = JOptionPane.getRootFrame().getSize();
@@ -76,7 +77,8 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
return null;
}
public FDeckChooser(boolean forAi) {
public FDeckChooser(final CDetailPicture cDetailPicture, final boolean forAi) {
lstDecks = new DeckManager(GameType.Constructed, cDetailPicture);
setOpaque(false);
isAi = forAi;
UiCommand cmdViewDeck = new UiCommand() {

View File

@@ -47,15 +47,15 @@ public class FDeckViewer extends FDialog {
public static void show(final Deck deck) {
if (deck == null) { return; }
FDeckViewer deckViewer = new FDeckViewer(deck);
final FDeckViewer deckViewer = new FDeckViewer(deck);
deckViewer.setVisible(true);
deckViewer.dispose();
}
private FDeckViewer(Deck deck0) {
private FDeckViewer(final Deck deck0) {
this.deck = deck0;
this.setTitle(deck.getName());
this.cardManager = new CardManager(false) {
this.cardManager = new CardManager(null, false) {
@Override //show hovered card in Image View in dialog instead of main Detail/Picture panes
protected ImageView<PaperCard> createImageView(final ItemManagerModel<PaperCard> model0) {
return new ImageView<PaperCard>(this, model0) {

View File

@@ -31,16 +31,15 @@ import javax.swing.border.EmptyBorder;
import org.apache.commons.lang3.StringUtils;
import forge.card.CardDetailUtil;
import forge.card.CardRarity;
import forge.card.CardDetailUtil.DetailColors;
import forge.card.CardEdition;
import forge.card.CardRarity;
import forge.game.card.Card;
import forge.game.card.CardView;
import forge.game.card.CardView.CardStateView;
import forge.game.zone.ZoneType;
import forge.item.IPaperCard;
import forge.item.InventoryItemFromSet;
import forge.match.MatchUtil;
import forge.model.FModel;
import forge.toolbox.FHtmlViewer;
import forge.toolbox.FLabel;
@@ -189,7 +188,7 @@ public class CardDetailPanel extends SkinnedPanel {
return;
}
boolean canShow = MatchUtil.canCardBeShown(card);
boolean canShow = true;
if (state.getManaCost().isNoCost() || !canShow) {
nameCostLabel.setText(CardDetailUtil.formatCardName(card, canShow, isInAltState));

View File

@@ -73,7 +73,7 @@ public final class CardPicturePanel extends JPanel {
}
}
public BufferedImage getImage() {
private BufferedImage getImage() {
if (displayed instanceof InventoryItem) {
final InventoryItem item = (InventoryItem) displayed;
return ImageCache.getOriginalImage(ImageKeys.getImageKey(item, false), true);

View File

@@ -69,11 +69,11 @@ public class DualListBox<T> extends FDialog {
private boolean sideboardingMode = false;
private boolean showCard = true;
public DualListBox(int remainingSources, List<T> sourceElements, List<T> destElements) {
this(remainingSources, remainingSources, sourceElements, destElements);
}
private final CMatchUI matchUI;
public DualListBox(final int remainingSourcesMin, final int remainingSourcesMax, final List<T> sourceElements, final List<T> destElements, final CMatchUI matchUI) {
this.matchUI = matchUI;
public DualListBox(int remainingSourcesMin, int remainingSourcesMax, List<T> sourceElements, List<T> destElements) {
targetRemainingSourcesMin = remainingSourcesMin;
targetRemainingSourcesMax = remainingSourcesMax;
sourceListModel = new UnsortedListModel<T>();
@@ -152,15 +152,15 @@ public class DualListBox<T> extends FDialog {
autoButton = new FButton("Auto");
autoButton.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) { _addAll(); _finish(); } });
FPanel leftPanel = new FPanel(new BorderLayout());
final FPanel leftPanel = new FPanel(new BorderLayout());
selectOrder = new FLabel.Builder().text("Select Order:").build();
leftPanel.add(selectOrder, BorderLayout.NORTH);
leftPanel.add(new FScrollPane(sourceList, true), BorderLayout.CENTER);
leftPanel.add(okButton, BorderLayout.SOUTH);
FPanel centerPanel = new FPanel(new GridLayout(6, 1));
final FPanel centerPanel = new FPanel(new GridLayout(6, 1));
centerPanel.setBorderToggle(false);
JPanel emptyPanel = new JPanel();
final JPanel emptyPanel = new JPanel();
emptyPanel.setOpaque(false);
centerPanel.add(emptyPanel); // empty panel to take up the first slot
centerPanel.add(addButton);
@@ -170,7 +170,7 @@ public class DualListBox<T> extends FDialog {
orderedLabel = new FLabel.Builder().build();
FPanel rightPanel = new FPanel(new BorderLayout());
final FPanel rightPanel = new FPanel(new BorderLayout());
rightPanel.add(orderedLabel, BorderLayout.NORTH);
rightPanel.add(new FScrollPane(destList, true), BorderLayout.CENTER);
rightPanel.add(autoButton, BorderLayout.SOUTH);
@@ -337,10 +337,12 @@ public class DualListBox<T> extends FDialog {
card = Card.getCardForUi((IPaperCard) obj).getView();
}
GuiUtils.clearPanelSelections();
if (matchUI != null) {
matchUI.clearPanelSelections();
if (card != null) {
CMatchUI.SINGLETON_INSTANCE.setCard(card);
GuiUtils.setPanelSelection(card);
matchUI.setCard(card);
matchUI.setPanelSelection(card);
}
}
}

View File

@@ -188,6 +188,9 @@ public class GuiChoose {
}
public static <T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices, final T selected, final Function<T, String> display) {
return getChoices(message, min, max, choices, selected, display, null);
}
public static <T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices, final T selected, final Function<T, String> display, final CMatchUI matchUI) {
if (choices == null || choices.isEmpty()) {
if (min == 0) {
return new ArrayList<T>();
@@ -195,17 +198,18 @@ public class GuiChoose {
throw new RuntimeException("choice required from empty list");
}
Callable<List<T>> showChoice = new Callable<List<T>>() {
final Callable<List<T>> showChoice = new Callable<List<T>>() {
@Override
public List<T> call() {
ListChooser<T> c = new ListChooser<T>(message, min, max, choices, display);
final JList<T> list = c.getLstChoices();
if (matchUI != null) {
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(final ListSelectionEvent ev) {
final T sel = list.getSelectedValue();
if (sel instanceof InventoryItem) {
CMatchUI.SINGLETON_INSTANCE.setCard((InventoryItem) list.getSelectedValue());
matchUI.setCard((InventoryItem) list.getSelectedValue());
return;
}
@@ -218,13 +222,14 @@ public class GuiChoose {
card = null;
}
if (card != null) {
CMatchUI.SINGLETON_INSTANCE.setCard(card);
matchUI.setCard(card);
GuiUtils.clearPanelSelections();
GuiUtils.setPanelSelection(card);
matchUI.clearPanelSelections();
matchUI.setPanelSelection(card);
}
}
});
}
if (selected != null) {
c.show(selected);
@@ -233,7 +238,9 @@ public class GuiChoose {
c.show();
}
GuiUtils.clearPanelSelections();
if (matchUI != null) {
matchUI.clearPanelSelections();
}
return c.getSelectedValues();
}
};
@@ -248,34 +255,28 @@ public class GuiChoose {
return null;
}
public static <T> List<T> many(final String title, final String topCaption, int cnt, final List<T> sourceChoices, final CardView referenceCard) {
return order(title, topCaption, cnt, cnt, sourceChoices, null, referenceCard, false);
}
public static <T> List<T> many(final String title, final String topCaption, int min, int max, final List<T> sourceChoices, final CardView referenceCard) {
int m2 = min >= 0 ? sourceChoices.size() - min : -1;
int m1 = max >= 0 ? sourceChoices.size() - max : -1;
return order(title, topCaption, m1, m2, sourceChoices, null, referenceCard, false);
}
public static <T> List<T> order(final String title, final String top, final List<T> sourceChoices, final CardView referenceCard) {
return order(title, top, 0, 0, sourceChoices, null, referenceCard, false);
}
public static <T extends Comparable<? super T>> List<T> sideboard(List<T> sideboard, List<T> deck) {
public static <T extends Comparable<? super T>> List<T> sideboard(final CMatchUI matchUI, final List<T> sideboard, final List<T> deck) {
Collections.sort(deck);
Collections.sort(sideboard);
return order("Sideboard", "Main Deck", -1, -1, sideboard, deck, null, true);
}
public static <T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
final List<T> sourceChoices, final List<T> destChoices) {
return order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, null, false, null);
}
public static <T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
final List<T> sourceChoices, final List<T> destChoices, final CardView referenceCard, final boolean sideboardingMode) {
return order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode, null);
}
public static <T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
final List<T> sourceChoices, final List<T> destChoices, final CardView referenceCard, final boolean sideboardingMode, final CMatchUI matchUI) {
// An input box for handling the order of choices.
Callable<List<T>> callable = new Callable<List<T>>() {
@Override
public List<T> call() throws Exception {
DualListBox<T> dual = new DualListBox<T>(remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices);
DualListBox<T> dual = new DualListBox<T>(remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, matchUI);
dual.setSecondColumnLabelText(top);
dual.setSideboardMode(sideboardingMode);
@@ -283,8 +284,8 @@ public class GuiChoose {
dual.setTitle(title);
dual.pack();
dual.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
if (referenceCard != null) {
CMatchUI.SINGLETON_INSTANCE.setCard(referenceCard);
if (matchUI != null && referenceCard != null) {
matchUI.setCard(referenceCard);
// MARKED FOR UPDATE
}
dual.setVisible(true);
@@ -292,7 +293,9 @@ public class GuiChoose {
List<T> objects = dual.getOrderedList();
dual.dispose();
GuiUtils.clearPanelSelections();
if (matchUI != null) {
matchUI.clearPanelSelections();
}
return objects;
}
};

View File

@@ -20,21 +20,24 @@ public class GuiDialog {
private static final String[] defaultConfirmOptions = { "Yes", "No" };
public static boolean confirm(final CardView c, final String question) {
return GuiDialog.confirm(c, question, true, null);
return confirm(c, question, true, null);
}
public static boolean confirm(final CardView c, final String question, final boolean defaultChoice) {
return GuiDialog.confirm(c, question, defaultChoice, null);
return confirm(c, question, defaultChoice, null);
}
public static boolean confirm(final CardView c, final String question, String[] options) {
return GuiDialog.confirm(c, question, true, options);
return confirm(c, question, true, options);
}
public static boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final String[] options) {
return confirm(c, question, defaultIsYes, options, null);
}
public static boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final String[] options, final CMatchUI matchUI) {
Callable<Boolean> confirmTask = new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
if (c != null) {
CMatchUI.SINGLETON_INSTANCE.setCard(c);
if (matchUI != null && c != null) {
matchUI.setCard(c);
}
final String title = c == null ? "Question" : c + " - Ability";

View File

@@ -24,7 +24,6 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
@@ -32,11 +31,6 @@ import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.KeyStroke;
import forge.game.card.CardView;
import forge.screens.match.VMatchUI;
import forge.screens.match.views.VField;
import forge.view.arcane.CardPanel;
/**
* <p>
* GuiUtils class.
@@ -72,37 +66,6 @@ public final class GuiUtils {
return ttf;
}
/**
* Clear all visually highlighted card panels on the battlefield.
*/
public static void clearPanelSelections() {
List<VField> view = VMatchUI.SINGLETON_INSTANCE.getFieldViews();
for (VField v : view) {
for (CardPanel p : v.getTabletop().getCardPanels()) {
p.setSelected(false);
}
}
}
/**
* Highlight a card on the playfield.
*
* @param card
* a card to be highlighted
*/
public static void setPanelSelection(final CardView card) {
mainLoop:
for (final VField v : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) {
final List<CardPanel> panels = v.getTabletop().getCardPanels();
for (final CardPanel p : panels) {
if (p.getCard().equals(card)) {
p.setSelected(true);
break mainLoop;
}
}
}
}
private static final int minItemWidth = 100;
private static final int itemHeight = 25;

View File

@@ -1,22 +1,25 @@
package forge.gui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.FocusManager;
import javax.swing.JPanel;
import javax.swing.Timer;
import net.miginfocom.swing.MigLayout;
import forge.Singletons;
import forge.assets.FSkinProp;
import forge.screens.match.TargetingOverlay;
import forge.toolbox.FLabel;
import forge.toolbox.FOverlay;
import forge.toolbox.FPanel;
import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinnedButton;
import forge.toolbox.FSkin.SkinnedLabel;
import net.miginfocom.swing.MigLayout;
import javax.swing.FocusManager;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* All overlay interaction is handled here.
@@ -148,14 +151,4 @@ public final class SOverlayUtils {
_overlayHasFocus = false;
}
public static void showTargetingOverlay() {
TargetingOverlay.SINGLETON_INSTANCE.getPanel().setVisible(true);
}
/**
* Removes child components and closes overlay.
*/
public static void hideTargetingOverlay() {
TargetingOverlay.SINGLETON_INSTANCE.getPanel().setVisible(false);
}
}

View File

@@ -16,6 +16,10 @@ public class CEmptyDoc implements ICDoc {
return null;
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#initialize()
*/

View File

@@ -3,13 +3,23 @@
*/
package forge.gui.framework;
import forge.screens.deckeditor.views.*;
import forge.screens.deckeditor.views.VAllDecks;
import forge.screens.deckeditor.views.VCardCatalog;
import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.deckeditor.views.VDeckgen;
import forge.screens.deckeditor.views.VProbabilities;
import forge.screens.deckeditor.views.VStatistics;
import forge.screens.home.gauntlet.VSubmenuGauntletBuild;
import forge.screens.home.gauntlet.VSubmenuGauntletContests;
import forge.screens.home.gauntlet.VSubmenuGauntletLoad;
import forge.screens.home.gauntlet.VSubmenuGauntletQuick;
import forge.screens.home.online.VSubmenuOnlineLobby;
import forge.screens.home.quest.*;
import forge.screens.home.quest.VSubmenuChallenges;
import forge.screens.home.quest.VSubmenuDuels;
import forge.screens.home.quest.VSubmenuQuestData;
import forge.screens.home.quest.VSubmenuQuestDecks;
import forge.screens.home.quest.VSubmenuQuestDraft;
import forge.screens.home.quest.VSubmenuQuestPrefs;
import forge.screens.home.sanctioned.VSubmenuConstructed;
import forge.screens.home.sanctioned.VSubmenuDraft;
import forge.screens.home.sanctioned.VSubmenuSealed;
@@ -19,7 +29,6 @@ import forge.screens.home.settings.VSubmenuAvatars;
import forge.screens.home.settings.VSubmenuDownloaders;
import forge.screens.home.settings.VSubmenuPreferences;
import forge.screens.home.settings.VSubmenuReleaseNotes;
import forge.screens.match.views.*;
import forge.screens.workshop.views.VCardDesigner;
import forge.screens.workshop.views.VCardScript;
import forge.screens.workshop.views.VWorkshopCatalog;
@@ -31,9 +40,9 @@ import forge.screens.workshop.views.VWorkshopCatalog;
* <br><br><i>(E at beginning of class name denotes an enum.)</i>
*/
public enum EDocID {
CARD_PICTURE (VPicture.SINGLETON_INSTANCE),
CARD_DETAIL (VDetail.SINGLETON_INSTANCE),
CARD_ANTES (VAntes.SINGLETON_INSTANCE),
CARD_PICTURE (),
CARD_DETAIL (),
CARD_ANTES (),
EDITOR_ALLDECKS (VAllDecks.SINGLETON_INSTANCE),
EDITOR_STATISTICS (VStatistics.SINGLETON_INSTANCE),
@@ -67,53 +76,63 @@ public enum EDocID {
HOME_LOBBY (VSubmenuOnlineLobby.SINGLETON_INSTANCE),
HOME_RELEASE_NOTES (VSubmenuReleaseNotes.SINGLETON_INSTANCE),
REPORT_MESSAGE (VPrompt.SINGLETON_INSTANCE),
REPORT_STACK (VStack.SINGLETON_INSTANCE),
REPORT_COMBAT (VCombat.SINGLETON_INSTANCE),
REPORT_LOG (VLog.SINGLETON_INSTANCE),
REPORT_PLAYERS (VPlayers.SINGLETON_INSTANCE),
REPORT_MESSAGE (),
REPORT_STACK (),
REPORT_COMBAT (),
REPORT_LOG (),
REPORT_PLAYERS (),
DEV_MODE (VDev.SINGLETON_INSTANCE),
BUTTON_DOCK (VDock.SINGLETON_INSTANCE),
DEV_MODE (),
BUTTON_DOCK (),
// Non-user battlefields (AI or teammate), use setDoc to register.
FIELD_0 (null),
FIELD_1 (null),
FIELD_2 (null),
FIELD_3 (null),
FIELD_4 (null),
FIELD_5 (null),
FIELD_6 (null),
FIELD_7 (null),
// Battlefields, use setDoc to register.
FIELD_0 (),
FIELD_1 (),
FIELD_2 (),
FIELD_3 (),
FIELD_4 (),
FIELD_5 (),
FIELD_6 (),
FIELD_7 (),
// Non-user hands (AI or teammate), use setDoc to register.
HAND_0 (null),
HAND_1 (null),
HAND_2 (null),
HAND_3 (null),
HAND_4 (null),
HAND_5 (null),
HAND_6 (null),
HAND_7 (null),
// Hands, use setDoc to register.
HAND_0 (),
HAND_1 (),
HAND_2 (),
HAND_3 (),
HAND_4 (),
HAND_5 (),
HAND_6 (),
HAND_7 (),
COMMAND_0 (null),
COMMAND_1 (null),
COMMAND_2 (null),
COMMAND_3 (null),
COMMAND_4 (null),
COMMAND_5 (null),
COMMAND_6 (null),
COMMAND_7 (null);
// Command zones, use setDoc to register.
COMMAND_0 (),
COMMAND_1 (),
COMMAND_2 (),
COMMAND_3 (),
COMMAND_4 (),
COMMAND_5 (),
COMMAND_6 (),
COMMAND_7 ();
public final static EDocID[] Commands = new EDocID[] {COMMAND_0, COMMAND_1, COMMAND_2, COMMAND_3, COMMAND_4, COMMAND_5, COMMAND_6, COMMAND_7};
public final static EDocID[] Fields = new EDocID[] {FIELD_0, FIELD_1, FIELD_2, FIELD_3, FIELD_4, FIELD_5, FIELD_6, FIELD_7};
public final static EDocID[] Hands = new EDocID[] {HAND_0, HAND_1, HAND_2, HAND_3, HAND_4, HAND_5, HAND_6, HAND_7};
static {
for (int i = 0; i < 8; i++) EDocID.Fields[i].setDoc(new VEmptyDoc(EDocID.Fields[i]));
for (int i = 0; i < 8; i++) EDocID.Commands[i].setDoc(new VEmptyDoc(EDocID.Commands[i]));
for (int i = 0; i < 8; i++) EDocID.Hands[i].setDoc(new VEmptyDoc(EDocID.Hands[i]));
}
// End enum declarations, start enum methods.
private IVDoc<? extends ICDoc> vDoc;
private EDocID() {
this(null);
}
/** @param doc0 &emsp; {@link forge.gui.framework.IVDoc} */
EDocID(final IVDoc<? extends ICDoc> doc0) {
private EDocID(final IVDoc<? extends ICDoc> doc0) {
this.vDoc = doc0;
}
@@ -124,7 +143,7 @@ public enum EDocID {
/** @return {@link forge.gui.framework.IVDoc} */
public IVDoc<? extends ICDoc> getDoc() {
if (vDoc == null) { throw new NullPointerException("No document found for " + this.name() + "."); }
//if (vDoc == null) { throw new NullPointerException("No document found for " + this.name() + "."); }
return vDoc;
}
}

View File

@@ -1,5 +1,7 @@
package forge.gui.framework;
import java.io.File;
import forge.Singletons;
import forge.assets.FSkinProp;
import forge.properties.FileLocation;
@@ -17,144 +19,152 @@ import forge.screens.workshop.VWorkshopUI;
import forge.toolbox.FOptionPane;
import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinImage;
import java.io.File;
import forge.view.FView;
/**
* Definitions for Forge screens
*
*/
public enum FScreen {
HOME_SCREEN(
public class FScreen {
public static final FScreen HOME_SCREEN = new FScreen(
VHomeUI.SINGLETON_INSTANCE,
CHomeUI.SINGLETON_INSTANCE,
"Home",
FSkin.getIcon(FSkinProp.ICO_FAVICON),
false,
"Exit Forge",
null),
MATCH_SCREEN(
VMatchUI.SINGLETON_INSTANCE,
CMatchUI.SINGLETON_INSTANCE,
"Game",
FSkin.getIcon(FSkinProp.ICO_ALPHASTRIKE), //TODO: Create icon for match screen
true,
"Concede Game",
ForgeConstants.MATCH_LAYOUT_FILE),
WORKSHOP_SCREEN(
null,
false);
public static final FScreen WORKSHOP_SCREEN = new FScreen(
VWorkshopUI.SINGLETON_INSTANCE,
CWorkshopUI.SINGLETON_INSTANCE,
"Workshop",
FSkin.getIcon(FSkinProp.ICO_SETTINGS), //TODO: Create icon for workshop screen
false,
"Back to Home",
ForgeConstants.WORKSHOP_LAYOUT_FILE),
DECK_EDITOR_CONSTRUCTED(
ForgeConstants.WORKSHOP_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_CONSTRUCTED = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
false,
"Back to Home",
ForgeConstants.EDITOR_LAYOUT_FILE),
DECK_EDITOR_ARCHENEMY(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_ARCHENEMY = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Scheme Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE),
DECK_EDITOR_COMMANDER(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_COMMANDER = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Commander Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE),
DECK_EDITOR_PLANECHASE(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_PLANECHASE = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Planar Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE),
DECK_EDITOR_VANGUARD(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_VANGUARD = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Vanguard Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE),
DECK_EDITOR_DRAFT(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_DRAFT = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Draft Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE),
DECK_EDITOR_SEALED(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_SEALED = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Sealed Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE),
DECK_EDITOR_QUEST(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_QUEST = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Quest Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE),
DECK_EDITOR_QUEST_TOURNAMENT(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_QUEST_TOURNAMENT = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Quest Tournament Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE),
QUEST_CARD_SHOP(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen QUEST_CARD_SHOP = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Spell Shop",
FSkin.getIcon(FSkinProp.ICO_QUEST_BOOK),
true,
"Leave Shop",
ForgeConstants.EDITOR_LAYOUT_FILE),
DRAFTING_PROCESS(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DRAFTING_PROCESS = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Draft",
FSkin.getImage(FSkinProp.IMG_ZONE_HAND),
true,
"Leave Draft",
ForgeConstants.EDITOR_LAYOUT_FILE),
QUEST_BAZAAR(
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen QUEST_BAZAAR = new FScreen(
VBazaarUI.SINGLETON_INSTANCE,
CBazaarUI.SINGLETON_INSTANCE,
"Bazaar",
FSkin.getIcon(FSkinProp.ICO_QUEST_BOTTLES),
true,
"Leave Bazaar",
null);
null,
false);
private final IVTopLevelUI view;
private final ICDoc controller;
private final String tabCaption;
private String tabCaption;
private final SkinImage tabIcon;
private final boolean allowTabClose;
private final String closeButtonTooltip;
private final FileLocation layoutFile;
private final boolean isMatch;
private FScreen(IVTopLevelUI view0, ICDoc controller0, String tabCaption0, SkinImage tabIcon0, boolean allowTabClose0, String closeButtonTooltip0, FileLocation layoutFile0) {
private FScreen(final IVTopLevelUI view0, final ICDoc controller0,
final String tabCaption0, final SkinImage tabIcon0,
final boolean allowTabClose0, final String closeButtonTooltip0,
final FileLocation layoutFile0, final boolean isMatch) {
this.view = view0;
this.controller = controller0;
this.tabCaption = tabCaption0;
@@ -162,6 +172,19 @@ public enum FScreen {
this.allowTabClose = allowTabClose0;
this.closeButtonTooltip = closeButtonTooltip0;
this.layoutFile = layoutFile0;
this.isMatch = isMatch;
}
public static FScreen getMatchScreen(final CMatchUI controller, final VMatchUI view) {
return new FScreen(
view,
controller,
"Game",
FSkin.getIcon(FSkinProp.ICO_ALPHASTRIKE), //TODO: Create icon for match screen
true,
"Concede Game",
ForgeConstants.MATCH_LAYOUT_FILE,
true);
}
public IVTopLevelUI getView() {
@@ -175,6 +198,10 @@ public enum FScreen {
public String getTabCaption() {
return tabCaption;
}
public void setTabCaption(final String caption) {
this.tabCaption = caption;
FView.SINGLETON_INSTANCE.getNavigationBar().updateTitle(this);
}
public SkinImage getTabIcon() {
return tabIcon;
@@ -202,17 +229,22 @@ public enum FScreen {
public boolean deleteLayoutFile() {
if (layoutFile == null) { return false; }
try {
File file = new File(layoutFile.userPrefLoc);
file.delete();
return true;
return deleteLayoutFile(layoutFile);
}
catch (final Exception e) {
public static boolean deleteMatchLayoutFile() {
return deleteLayoutFile(ForgeConstants.MATCH_LAYOUT_FILE);
}
private static boolean deleteLayoutFile(final FileLocation file) {
try {
File f = new File(file.userPrefLoc);
f.delete();
return true;
} catch (final Exception e) {
e.printStackTrace();
FOptionPane.showErrorDialog("Failed to delete layout file.");
}
return false;
}
public void open() {
@@ -222,4 +254,8 @@ public enum FScreen {
public void close() {
Singletons.getView().getNavigationBar().closeTab(this);
}
public boolean isMatchScreen() {
return isMatch;
}
}

View File

@@ -3,28 +3,33 @@ package forge.gui.framework;
import forge.UiCommand;
/**
* Dictates methods required for any controller
* of an {@link forge.gui.framework.IVDoc}.
* Dictates methods required for any controller of an
* {@link forge.gui.framework.IVDoc}.
*
* <br><br><i>(I at beginning of class name denotes an interface.)</i>
* <br><i>(C at beginning of class name denotes a controller class.)</i>
* <br>
* <br>
* <i>(I at beginning of class name denotes an interface.)</i><br>
* <i>(C at beginning of class name denotes a controller class.)</i>
*/
public interface ICDoc {
/**
* Fires when this controller's view tab is selected.
* Since this method is fired when all tabs are first
* initialized, be wary of NPEs created by referring to
* non-existent components.
* Fires when this controller's view tab is selected. Since this method is
* fired when all tabs are first initialized, be wary of NPEs created by
* referring to non-existent components.
*
* @return {@link forge.UiCommand} */
* @return {@link forge.UiCommand}
*/
UiCommand getCommandOnSelect();
/**
* This method is called once, after the view singleton has been fully realized
* for the first time. It should execute operations which should only
* be done once, but require non-null view components.
* <br><br>
* This method should only be called once, in FView, after singletons are populated.
* Asks this controller to register its docs, so that a layout can be
* applied to them.
*/
void register();
/**
* This method is called every time the user switches to the tab containing
* this item.
*/
void initialize();

View File

@@ -1,9 +1,13 @@
package forge.gui.framework;
import forge.FThreads;
import forge.Singletons;
import forge.gui.SOverlayUtils;
import forge.properties.FileLocation;
import forge.properties.ForgeConstants;
import forge.toolbox.FAbsolutePositioner;
import forge.toolbox.SaveOpenDialog;
import forge.toolbox.SaveOpenDialog.Filetypes;
import forge.util.CollectionSuppliers;
import forge.util.ThreadUtil;
import forge.util.maps.HashMapOfLists;
@@ -49,6 +53,54 @@ public final class SLayoutIO {
private final static AtomicBoolean saveWindowRequested = new AtomicBoolean(false);
public static void saveLayout() {
final SaveOpenDialog dlgSave = new SaveOpenDialog();
final FileLocation layoutFile = Singletons.getControl().getCurrentScreen().getLayoutFile();
final File defFile = layoutFile != null ? new File(layoutFile.userPrefLoc) : null;
final File saveFile = dlgSave.SaveDialog(defFile, Filetypes.LAYOUT);
if (saveFile != null) {
SLayoutIO.saveLayout(saveFile);
}
}
public static void openLayout() {
SOverlayUtils.genericOverlay();
final SaveOpenDialog dlgOpen = new SaveOpenDialog();
final FileLocation layoutFile = Singletons.getControl().getCurrentScreen().getLayoutFile();
final File defFile = layoutFile != null ? new File(layoutFile.userPrefLoc) : null;
final File loadFile = dlgOpen.OpenDialog(defFile, Filetypes.LAYOUT);
if (loadFile != null) {
FView.SINGLETON_INSTANCE.getPnlContent().removeAll();
// let it redraw everything first
FThreads.invokeInEdtLater(new Runnable() {
@Override
public void run() {
if (loadFile != null) {
SLayoutIO.loadLayout(loadFile);
SLayoutIO.saveLayout(null);
}
SOverlayUtils.hideOverlay();
}
});
}
}
public static void revertLayout() {
SOverlayUtils.genericOverlay();
FView.SINGLETON_INSTANCE.getPnlContent().removeAll();
FThreads.invokeInEdtLater(new Runnable(){
@Override public void run() {
SLayoutIO.loadLayout(null);
SOverlayUtils.hideOverlay();
}
});
}
public static void saveWindowLayout() {
if (saveWindowRequested.getAndSet(true)) { return; }
ThreadUtil.delay(500, new Runnable() {

View File

@@ -7,6 +7,8 @@ import forge.itemmanager.filters.*;
import forge.model.FModel;
import forge.quest.QuestWorld;
import forge.screens.home.quest.DialogChooseSets;
import forge.screens.match.controllers.CDetailPicture;
import javax.swing.*;
import java.util.HashMap;
@@ -19,8 +21,8 @@ import java.util.Map.Entry;
*/
@SuppressWarnings("serial")
public class CardManager extends ItemManager<PaperCard> {
public CardManager(boolean wantUnique0) {
super(PaperCard.class, wantUnique0);
public CardManager(final CDetailPicture cDetailPicture, final boolean wantUnique0) {
super(PaperCard.class, cDetailPicture, wantUnique0);
}
@Override

View File

@@ -1,5 +1,23 @@
package forge.itemmanager;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.swing.JMenu;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.apache.commons.lang3.StringUtils;
import forge.Singletons;
import forge.UiCommand;
import forge.assets.FSkinProp;
@@ -12,7 +30,13 @@ import forge.game.IHasGameType;
import forge.gui.GuiUtils;
import forge.gui.framework.FScreen;
import forge.item.InventoryItem;
import forge.itemmanager.filters.*;
import forge.itemmanager.filters.DeckColorFilter;
import forge.itemmanager.filters.DeckFolderFilter;
import forge.itemmanager.filters.DeckFormatFilter;
import forge.itemmanager.filters.DeckQuestWorldFilter;
import forge.itemmanager.filters.DeckSearchFilter;
import forge.itemmanager.filters.DeckSetFilter;
import forge.itemmanager.filters.ItemFilter;
import forge.itemmanager.views.ItemCellRenderer;
import forge.itemmanager.views.ItemListView;
import forge.itemmanager.views.ItemTableColumn;
@@ -24,21 +48,10 @@ import forge.screens.deckeditor.controllers.ACEditorBase;
import forge.screens.deckeditor.controllers.CEditorLimited;
import forge.screens.deckeditor.controllers.CEditorQuest;
import forge.screens.home.quest.DialogChooseSets;
import forge.screens.match.controllers.CDetailPicture;
import forge.toolbox.FOptionPane;
import forge.toolbox.FSkin;
import org.apache.commons.lang3.StringUtils;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
import java.util.Map.Entry;
/**
* ItemManager for decks
*
@@ -59,8 +72,8 @@ public final class DeckManager extends ItemManager<DeckProxy> implements IHasGam
*
* @param gt
*/
public DeckManager(final GameType gt) {
super(DeckProxy.class, true);
public DeckManager(final GameType gt, final CDetailPicture cDetailPicture) {
super(DeckProxy.class, cDetailPicture, true);
this.gameType = gt;
this.addSelectionListener(new ListSelectionListener() {

View File

@@ -31,6 +31,7 @@ import forge.itemmanager.ItemManagerConfig;
import forge.itemmanager.ItemManagerModel;
import forge.itemmanager.filters.ItemFilter;
import forge.itemmanager.views.*;
import forge.screens.match.controllers.CDetailPicture;
import forge.toolbox.*;
import forge.toolbox.FSkin.Colors;
import forge.toolbox.FSkin.SkinIcon;
@@ -74,6 +75,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel implem
private UiCommand itemActivateCommand;
private ContextMenuBuilder contextMenuBuilder;
private final Class<T> genericType;
private final CDetailPicture cDetailPicture;
private ItemManagerConfig config;
private final ArrayList<ListSelectionListener> selectionListeners = new ArrayList<ListSelectionListener>();
@@ -125,7 +127,8 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel implem
* @param statLabels0 stat labels for this item manager
* @param wantUnique0 whether this table should display only one item with the same name
*/
protected ItemManager(final Class<T> genericType0, final boolean wantUnique0) {
protected ItemManager(final Class<T> genericType0, final CDetailPicture cDetailPicture, final boolean wantUnique0) {
this.cDetailPicture = cDetailPicture;
this.genericType = genericType0;
this.wantUnique = wantUnique0;
this.model = new ItemManagerModel<T>(genericType0);
@@ -144,6 +147,10 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel implem
return new ImageView<T>(this, model0);
}
public final CDetailPicture getCDetailPicture() {
return cDetailPicture;
}
/**
* Initialize item manager if needed
*/

View File

@@ -2,6 +2,7 @@ package forge.itemmanager;
import forge.item.InventoryItem;
import forge.itemmanager.filters.ItemFilter;
import forge.screens.match.controllers.CDetailPicture;
import javax.swing.*;
@@ -11,8 +12,8 @@ import javax.swing.*;
*/
@SuppressWarnings("serial")
public final class SpellShopManager extends ItemManager<InventoryItem> {
public SpellShopManager(boolean wantUnique0) {
super(InventoryItem.class, wantUnique0);
public SpellShopManager(final CDetailPicture cDetailPicture, final boolean wantUnique0) {
super(InventoryItem.class, cDetailPicture, wantUnique0);
}
@Override

View File

@@ -1,5 +1,34 @@
package forge.itemmanager.views;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JViewport;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import forge.ImageCache;
import forge.assets.FSkinProp;
import forge.deck.DeckProxy;
@@ -14,26 +43,19 @@ import forge.itemmanager.ItemManager;
import forge.itemmanager.ItemManagerConfig;
import forge.itemmanager.ItemManagerModel;
import forge.itemmanager.SItemManagerUtil;
import forge.screens.match.controllers.CDetail;
import forge.screens.match.controllers.CPicture;
import forge.toolbox.*;
import forge.screens.match.controllers.CDetailPicture;
import forge.toolbox.FComboBoxWrapper;
import forge.toolbox.FLabel;
import forge.toolbox.FMouseAdapter;
import forge.toolbox.FScrollPane;
import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinColor;
import forge.toolbox.FSkin.SkinFont;
import forge.toolbox.FSkin.SkinImage;
import forge.toolbox.FTextField;
import forge.toolbox.special.CardZoomer;
import forge.view.arcane.CardPanel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
public class ImageView<T extends InventoryItem> extends ItemView<T> {
private static final int PADDING = 5;
private static final float PILE_SPACING_Y = 0.1f;
@@ -137,7 +159,7 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
private final FComboBoxWrapper<Object> cbPileByOptions = new FComboBoxWrapper<Object>();
private final FComboBoxWrapper<Integer> cbColumnCount = new FComboBoxWrapper<Integer>();
public ImageView(ItemManager<T> itemManager0, ItemManagerModel<T> model0) {
public ImageView(final ItemManager<T> itemManager0, final ItemManagerModel<T> model0) {
super(itemManager0, model0);
SItemManagerUtil.populateImageViewOptions(itemManager0, cbGroupByOptions, cbPileByOptions);
@@ -728,9 +750,11 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
return true;
}
protected void showHoveredItem(T item) {
CDetail.SINGLETON_INSTANCE.showCard(item);
CPicture.SINGLETON_INSTANCE.showImage(item);
protected void showHoveredItem(final T item) {
final CDetailPicture cDetailPicture = itemManager.getCDetailPicture();
if (cDetailPicture != null) {
cDetailPicture.showItem(item);
}
}
@Override

View File

@@ -1,5 +1,40 @@
package forge.itemmanager.views;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseWheelEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JViewport;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import forge.item.InventoryItem;
import forge.itemmanager.ColumnDef;
import forge.itemmanager.ItemManager;
@@ -9,24 +44,9 @@ import forge.toolbox.FLabel;
import forge.toolbox.FScrollPane;
import forge.toolbox.FScrollPanel;
import forge.toolbox.FSkin;
import forge.toolbox.ToolTipListener;
import forge.toolbox.FSkin.SkinColor;
import forge.toolbox.FSkin.SkinImage;
import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import forge.toolbox.ToolTipListener;
public abstract class ItemView<T extends InventoryItem> {
private static final SkinColor BORDER_COLOR = FSkin.getColor(FSkin.Colors.CLR_TEXT);
@@ -44,7 +64,7 @@ public abstract class ItemView<T extends InventoryItem> {
private boolean isIncrementalSearchActive = false;
@SuppressWarnings("serial")
protected ItemView(ItemManager<T> itemManager0, ItemManagerModel<T> model0) {
protected ItemView(final ItemManager<T> itemManager0, final ItemManagerModel<T> model0) {
this.itemManager = itemManager0;
this.model = model0;
this.scroller = new FScrollPane(false) {

View File

@@ -66,7 +66,7 @@ public final class ForgeMenu {
}
}
}
add(LayoutMenu.getMenu());
add(new LayoutMenu().getMenu());
add(HelpMenu.getMenu());
addSeparator();
add(getMenuItem_Restart());

View File

@@ -1,40 +1,46 @@
package forge.menus;
import java.awt.Cursor;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.KeyStroke;
import forge.Singletons;
import forge.assets.FSkinProp;
import forge.gui.GuiChoose;
import forge.gui.MouseUtil;
import forge.gui.framework.FScreen;
import forge.gui.framework.SLayoutIO;
import forge.model.FModel;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
import forge.screens.match.controllers.CDock;
import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinnedMenuItem;
import forge.view.FFrame;
import forge.view.FView;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
/**
* Returns a JMenu containing options associated with game screen layout.
* <p>
* Replicates options available in Dock tab.
*/
public final class LayoutMenu {
private LayoutMenu() { }
public LayoutMenu() {
}
private static final CDock controller = CDock.SINGLETON_INSTANCE;
private static FScreen currentScreen;
private FScreen currentScreen;
private static final ForgePreferences prefs = FModel.getPreferences();
private static boolean showIcons = false;
private boolean showIcons = false;
public static JMenu getMenu() {
public JMenu getMenu() {
currentScreen = Singletons.getControl().getCurrentScreen();
JMenu menu = new JMenu("Layout");
@@ -53,16 +59,16 @@ public final class LayoutMenu {
return menu;
}
private static JMenu getMenu_ViewOptions() {
private JMenu getMenu_ViewOptions() {
JMenu menu = new JMenu("View");
menu.add(getMenuItem_ShowTabs());
if (currentScreen == FScreen.MATCH_SCREEN) {
if (currentScreen != null && currentScreen.isMatchScreen()) {
menu.add(getMenuItem_ShowBackgroundImage());
}
return menu;
}
private static JMenu getMenu_FileOptions() {
private JMenu getMenu_FileOptions() {
JMenu menu = new JMenu("File");
menu.add(getMenuItem_OpenLayout());
menu.add(getMenuItem_SaveLayout());
@@ -138,50 +144,50 @@ public final class LayoutMenu {
};
}
private static JMenuItem getMenuItem_SaveLayout() {
private JMenuItem getMenuItem_SaveLayout() {
SkinnedMenuItem menuItem = new SkinnedMenuItem("Save Current Layout");
menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_SAVELAYOUT) : null));
menuItem.addActionListener(getSaveLayoutAction());
return menuItem;
}
private static ActionListener getSaveLayoutAction() {
private ActionListener getSaveLayoutAction() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.saveLayout();
SLayoutIO.saveLayout();
}
};
}
private static JMenuItem getMenuItem_OpenLayout() {
private JMenuItem getMenuItem_OpenLayout() {
SkinnedMenuItem menuItem = new SkinnedMenuItem("Open...");
menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_OPENLAYOUT) : null));
menuItem.addActionListener(getOpenLayoutAction());
return menuItem;
}
private static ActionListener getOpenLayoutAction() {
private ActionListener getOpenLayoutAction() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.openLayout();
SLayoutIO.openLayout();
}
};
}
private static JMenuItem getMenuItem_RevertLayout() {
private JMenuItem getMenuItem_RevertLayout() {
SkinnedMenuItem menuItem = new SkinnedMenuItem("Refresh");
menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_REVERTLAYOUT) : null));
menuItem.addActionListener(getRevertLayoutAction());
return menuItem;
}
private static ActionListener getRevertLayoutAction() {
private ActionListener getRevertLayoutAction() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.revertLayout();
SLayoutIO.revertLayout();
}
};
}

View File

@@ -51,6 +51,10 @@ public enum CBazaarUI implements ICDoc {
return null;
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#initialize()
*/

View File

@@ -17,32 +17,36 @@
*/
package forge.screens.deckeditor;
import forge.UiCommand;
import forge.Singletons;
import forge.deck.DeckBase;
import forge.deck.DeckProxy;
import forge.deck.io.DeckPreferences;
import forge.gui.framework.FScreen;
import forge.gui.framework.ICDoc;
import forge.item.InventoryItem;
import forge.itemmanager.ItemManager;
import forge.screens.deckeditor.controllers.*;
import forge.screens.deckeditor.views.VAllDecks;
import forge.screens.deckeditor.views.VCardCatalog;
import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.match.controllers.CDetail;
import forge.screens.match.controllers.CPicture;
import forge.util.ItemPool;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map.Entry;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import forge.Singletons;
import forge.UiCommand;
import forge.deck.DeckBase;
import forge.deck.DeckProxy;
import forge.deck.io.DeckPreferences;
import forge.gui.framework.EDocID;
import forge.gui.framework.FScreen;
import forge.gui.framework.ICDoc;
import forge.item.InventoryItem;
import forge.itemmanager.ItemManager;
import forge.screens.deckeditor.controllers.ACEditorBase;
import forge.screens.deckeditor.controllers.CEditorConstructed;
import forge.screens.deckeditor.controllers.CProbabilities;
import forge.screens.deckeditor.controllers.CStatistics;
import forge.screens.deckeditor.controllers.DeckController;
import forge.screens.deckeditor.views.VAllDecks;
import forge.screens.deckeditor.views.VCardCatalog;
import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.match.controllers.CDetailPicture;
import forge.util.ItemPool;
/**
* Constructs instance of deck editor UI controller, used as a single point of
* top-level control for child UIs. Tasks targeting the view of individual
@@ -57,9 +61,14 @@ public enum CDeckEditorUI implements ICDoc {
private final HashMap<FScreen, ACEditorBase<? extends InventoryItem, ? extends DeckBase>> screenChildControllers;
private ACEditorBase<? extends InventoryItem, ? extends DeckBase> childController;
private final CDetailPicture cDetailPicture;
private final VAllDecks vAllDecks;
private CDeckEditorUI() {
screenChildControllers = new HashMap<FScreen, ACEditorBase<? extends InventoryItem, ? extends DeckBase>>();
this.cDetailPicture = new CDetailPicture();
this.vAllDecks = VAllDecks.SINGLETON_INSTANCE;
this.vAllDecks.setCDetailPicture(cDetailPicture);
}
/**
@@ -67,8 +76,7 @@ public enum CDeckEditorUI implements ICDoc {
* @param item
*/
public void setCard(final InventoryItem item) {
CDetail.SINGLETON_INSTANCE.showCard(item);
CPicture.SINGLETON_INSTANCE.showImage(item);
cDetailPicture.showItem(item);
}
public boolean hasChanges() {
@@ -292,6 +300,12 @@ public enum CDeckEditorUI implements ICDoc {
return null;
}
@Override
public void register() {
EDocID.CARD_PICTURE.setDoc(cDetailPicture.getCPicture().getView());
EDocID.CARD_DETAIL.setDoc(cDetailPicture.getCDetail().getView());
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#initialize()
*/
@@ -308,9 +322,9 @@ public enum CDeckEditorUI implements ICDoc {
String currentDeckStr = DeckPreferences.getCurrentDeck();
if (currentDeckStr != null) {
DeckProxy deck = VAllDecks.SINGLETON_INSTANCE.getLstDecks().stringToItem(currentDeckStr);
DeckProxy deck = vAllDecks.getLstDecks().stringToItem(currentDeckStr);
if (deck != null) {
VAllDecks.SINGLETON_INSTANCE.getLstDecks().setSelectedItem(deck);
vAllDecks.getLstDecks().setSelectedItem(deck);
childController.getDeckController().load(deck.getPath(), deck.getName());
}
}

View File

@@ -36,6 +36,7 @@ import forge.screens.deckeditor.CDeckEditorUI;
import forge.screens.deckeditor.menus.CDeckEditorUIMenus;
import forge.screens.deckeditor.views.VCardCatalog;
import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.match.controllers.CDetailPicture;
import forge.toolbox.ContextMenuBuilder;
import forge.toolbox.FLabel;
import forge.toolbox.FSkin;
@@ -71,6 +72,7 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
private ItemManager<TItem> catalogManager;
private ItemManager<TItem> deckManager;
protected DeckSection sectionMode = DeckSection.Main;
private final CDetailPicture cDetailPicture = new CDetailPicture();
// card transfer buttons
private final FLabel btnAdd = new FLabel.Builder()
@@ -119,6 +121,10 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
return this.sectionMode;
}
protected final CDetailPicture getCDetailPicture() {
return cDetailPicture;
}
/* (non-Javadoc)
* @see forge.gui.menubar.IMenuProvider#getMenus()
*/
@@ -525,4 +531,5 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
KeyEvent.ALT_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
}
}
}

View File

@@ -26,6 +26,10 @@ public enum CAllDecks implements ICDoc {
return null;
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#initialize()
*/

View File

@@ -26,6 +26,10 @@ public enum CCardCatalog implements ICDoc {
return null;
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#initialize()
*/

View File

@@ -68,6 +68,10 @@ public enum CCurrentDeck implements ICDoc {
return null;
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#initialize()
*/

View File

@@ -44,6 +44,10 @@ public enum CDeckgen implements ICDoc {
return null;
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#initialize()
*/

View File

@@ -73,8 +73,8 @@ public final class CEditorCommander extends ACEditorBase<PaperCard, Deck> {
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.CAN_BE_COMMANDER, PaperCard.FN_GET_RULES)),PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(), PaperCard.class);
CardManager catalogManager = new CardManager(true);
CardManager deckManager = new CardManager(true);
CardManager catalogManager = new CardManager(getCDetailPicture(), true);
CardManager deckManager = new CardManager(getCDetailPicture(), true);
catalogManager.setCaption("Catalog");

View File

@@ -74,8 +74,8 @@ public final class CEditorConstructed extends ACEditorBase<PaperCard, Deck> {
schemePool = ItemPool.createFrom(FModel.getMagicDb().getVariantCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_SCHEME, PaperCard.FN_GET_RULES)), PaperCard.class);
conspiracyPool = ItemPool.createFrom(FModel.getMagicDb().getVariantCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_CONSPIRACY, PaperCard.FN_GET_RULES)), PaperCard.class);
CardManager catalogManager = new CardManager(false); // TODO: restore the functionality of the "want uniques only" toggle
CardManager deckManager = new CardManager(false); // IMPORTANT: must *always* show all cards in the deck, otherwise cards with different art get ignored!
CardManager catalogManager = new CardManager(getCDetailPicture(), false); // TODO: restore the functionality of the "want uniques only" toggle
CardManager deckManager = new CardManager(getCDetailPicture(), false); // IMPORTANT: must *always* show all cards in the deck, otherwise cards with different art get ignored!
catalogManager.setCaption("Catalog");

View File

@@ -66,8 +66,8 @@ public class CEditorDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
public CEditorDraftingProcess() {
super(FScreen.DRAFTING_PROCESS);
final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(false);
final CardManager catalogManager = new CardManager(getCDetailPicture(), false);
final CardManager deckManager = new CardManager(getCDetailPicture(), false);
//hide filters and options panel so more of pack is visible by default
catalogManager.setHideViewOptions(1, true);

View File

@@ -61,8 +61,8 @@ public final class CEditorLimited extends ACEditorBase<PaperCard, DeckGroup> {
public CEditorLimited(final IStorage<DeckGroup> deckMap0, FScreen screen0) {
super(screen0);
final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(false);
final CardManager catalogManager = new CardManager(getCDetailPicture(), false);
final CardManager deckManager = new CardManager(getCDetailPicture(), false);
catalogManager.setCaption("Sideboard");

View File

@@ -99,8 +99,8 @@ public final class CEditorQuest extends ACEditorBase<PaperCard, Deck> {
this.questData = questData0;
final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(false);
final CardManager catalogManager = new CardManager(getCDetailPicture(), false);
final CardManager deckManager = new CardManager(getCDetailPicture(), false);
catalogManager.setCaption("Quest Inventory");

View File

@@ -99,8 +99,8 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
this.questData = qd;
final SpellShopManager catalogManager = new SpellShopManager(false);
final SpellShopManager deckManager = new SpellShopManager(false);
final SpellShopManager catalogManager = new SpellShopManager(getCDetailPicture(), false);
final SpellShopManager deckManager = new SpellShopManager(getCDetailPicture(), false);
catalogManager.setCaption("Spell Shop");
deckManager.setCaption("Quest Inventory");

View File

@@ -78,8 +78,8 @@ public class CEditorQuestDraftingProcess extends ACEditorBase<PaperCard, DeckGro
public CEditorQuestDraftingProcess() {
super(FScreen.DRAFTING_PROCESS);
final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(false);
final CardManager catalogManager = new CardManager(getCDetailPicture(), false);
final CardManager deckManager = new CardManager(getCDetailPicture(), false);
//hide filters and options panel so more of pack is visible by default
catalogManager.setHideViewOptions(1, true);

View File

@@ -100,8 +100,8 @@ public final class CEditorQuestLimited extends ACEditorBase<PaperCard, DeckGroup
this.questData = questData0;
final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(false);
final CardManager catalogManager = new CardManager(getCDetailPicture(), false);
final CardManager deckManager = new CardManager(getCDetailPicture(), false);
catalogManager.setCaption("Sideboard");

View File

@@ -66,8 +66,8 @@ public final class CEditorVariant extends ACEditorBase<PaperCard, Deck> {
this.cardPoolCondition = poolCondition;
this.sectionMode = deckSection0;
CardManager catalogManager = new CardManager(true);
CardManager deckManager = new CardManager(true);
CardManager catalogManager = new CardManager(getCDetailPicture(), true);
CardManager deckManager = new CardManager(getCDetailPicture(), true);
catalogManager.setCaption("Catalog");

View File

@@ -76,8 +76,8 @@ public class CEditorWinstonProcess extends ACEditorBase<PaperCard, DeckGroup> {
public CEditorWinstonProcess() {
super(FScreen.DRAFTING_PROCESS);
final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(false);
final CardManager catalogManager = new CardManager(getCDetailPicture(), false);
final CardManager deckManager = new CardManager(getCDetailPicture(), false);
//hide filters and options panel so more of pack is visible by default
catalogManager.setHideViewOptions(1, true);

View File

@@ -32,6 +32,10 @@ public enum CProbabilities implements ICDoc {
return null;
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#initialize()
*/

View File

@@ -41,6 +41,10 @@ public enum CStatistics implements ICDoc {
return null;
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#initialize()
*/

View File

@@ -8,6 +8,7 @@ import forge.gui.framework.IVDoc;
import forge.itemmanager.DeckManager;
import forge.itemmanager.ItemManagerContainer;
import forge.screens.deckeditor.controllers.CAllDecks;
import forge.screens.match.controllers.CDetailPicture;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
@@ -25,12 +26,7 @@ public enum VAllDecks implements IVDoc<CAllDecks> {
private DragCell parentCell;
private final DragTab tab = new DragTab("All Decks");
private final DeckManager lstDecks = new DeckManager(GameType.Constructed);
//========== Constructor
private VAllDecks() {
lstDecks.setCaption("Decks");
}
private DeckManager lstDecks;
//========== Overridden methods
@@ -91,4 +87,9 @@ public enum VAllDecks implements IVDoc<CAllDecks> {
public DeckManager getLstDecks() {
return lstDecks;
}
public void setCDetailPicture(final CDetailPicture cDetailPicture) {
this.lstDecks = new DeckManager(GameType.Constructed, cDetailPicture);
this.lstDecks.setCaption("Decks");
}
}

View File

@@ -72,6 +72,10 @@ public enum CHomeUI implements ICDoc, IMenuProvider {
return lblSelected;
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.view.home.ICDoc#intialize()
*/
@@ -128,8 +132,7 @@ public enum CHomeUI implements ICDoc, IMenuProvider {
private void selectPrevious() {
EDocID selected = null;
try {
selected = EDocID.valueOf(FModel
.getPreferences().getPref(FPref.SUBMENU_CURRENTMENU));
selected = EDocID.valueOf(FModel.getPreferences().getPref(FPref.SUBMENU_CURRENTMENU));
} catch (final Exception e) { }
if (selected != null && VHomeUI.SINGLETON_INSTANCE.getAllSubmenuLabels().get(selected) != null) {

View File

@@ -83,6 +83,10 @@ public enum CSubmenuGauntletBuild implements ICDoc {
});
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.home.ICSubmenu#initialize()
*/

View File

@@ -1,5 +1,6 @@
package forge.screens.home.gauntlet;
import forge.GuiBase;
import forge.UiCommand;
import forge.deck.Deck;
import forge.game.GameType;
@@ -8,7 +9,7 @@ import forge.gauntlet.GauntletData;
import forge.gauntlet.GauntletIO;
import forge.gui.SOverlayUtils;
import forge.gui.framework.ICDoc;
import forge.match.MatchUtil;
import forge.match.HostedMatch;
import forge.model.FModel;
import forge.player.GamePlayerUtil;
@@ -51,6 +52,10 @@ public enum CSubmenuGauntletContests implements ICDoc {
});
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.home.ICSubmenu#initialize()
*/
@@ -82,8 +87,7 @@ public enum CSubmenuGauntletContests implements ICDoc {
if (gd.getUserDeck() != null) {
userDeck = gd.getUserDeck();
}
else {
} else {
userDeck = view.getLstDecks().getPlayer().getDeck();
gd.setUserDeck(userDeck);
}
@@ -99,14 +103,15 @@ public enum CSubmenuGauntletContests implements ICDoc {
}
});
Deck aiDeck = gd.getDecks().get(gd.getCompleted());
final Deck aiDeck = gd.getDecks().get(gd.getCompleted());
List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
starter.add(new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()));
final List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
final RegisteredPlayer human = new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer());
starter.add(human);
starter.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer()));
MatchUtil.startMatch(GameType.Gauntlet, starter);
final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch();
hostedMatch.startMatch(GameType.Gauntlet, null, starter, human, GuiBase.getInterface().getNewGuiGame());
}
/* (non-Javadoc)

View File

@@ -1,5 +1,6 @@
package forge.screens.home.gauntlet;
import forge.GuiBase;
import forge.UiCommand;
import forge.deck.Deck;
import forge.deck.DeckType;
@@ -10,7 +11,7 @@ import forge.gauntlet.GauntletData;
import forge.gauntlet.GauntletIO;
import forge.gui.SOverlayUtils;
import forge.gui.framework.ICDoc;
import forge.match.MatchUtil;
import forge.match.HostedMatch;
import forge.model.FModel;
import forge.player.GamePlayerUtil;
@@ -56,6 +57,10 @@ public enum CSubmenuGauntletLoad implements ICDoc {
});
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.home.ICSubmenu#initialize()
*/
@@ -113,7 +118,7 @@ public enum CSubmenuGauntletLoad implements ICDoc {
Deck userDeck = gd.getUserDeck();
if (userDeck == null) {
//give user a chance to select a deck if none saved with gauntlet
userDeck = FDeckChooser.promptForDeck("Select a deck to play for this gauntlet", DeckType.CUSTOM_DECK, false);
userDeck = FDeckChooser.promptForDeck(null, "Select a deck to play for this gauntlet", DeckType.CUSTOM_DECK, false);
if (userDeck == null) { return; } //prevent crash if user doesn't select a deck
gd.setUserDeck(userDeck);
GauntletIO.saveGauntlet(gd);
@@ -129,11 +134,13 @@ public enum CSubmenuGauntletLoad implements ICDoc {
}
});
List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
starter.add(new RegisteredPlayer(userDeck).setPlayer(GamePlayerUtil.getGuiPlayer()));
final List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
final RegisteredPlayer human = new RegisteredPlayer(userDeck).setPlayer(GamePlayerUtil.getGuiPlayer());
starter.add(human);
starter.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer()));
MatchUtil.startMatch(GameType.Gauntlet, starter);
final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch();
hostedMatch.startMatch(GameType.Gauntlet, null, starter, human, GuiBase.getInterface().getNewGuiGame());
}
/* (non-Javadoc)

View File

@@ -1,5 +1,6 @@
package forge.screens.home.gauntlet;
import forge.GuiBase;
import forge.UiCommand;
import forge.deck.DeckType;
import forge.game.GameType;
@@ -8,7 +9,7 @@ import forge.gauntlet.GauntletData;
import forge.gauntlet.GauntletUtil;
import forge.gui.SOverlayUtils;
import forge.gui.framework.ICDoc;
import forge.match.MatchUtil;
import forge.match.HostedMatch;
import forge.player.GamePlayerUtil;
import javax.swing.*;
@@ -44,6 +45,10 @@ public enum CSubmenuGauntletQuick implements ICDoc {
});
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.home.ICSubmenu#initialize()
*/
@@ -64,7 +69,7 @@ public enum CSubmenuGauntletQuick implements ICDoc {
});
// Find appropriate filename for new save, create and set new save file.
List<DeckType> allowedDeckTypes = new ArrayList<DeckType>();
final List<DeckType> allowedDeckTypes = new ArrayList<DeckType>();
if (view.getBoxColorDecks().isSelected()) { allowedDeckTypes.add(DeckType.COLOR_DECK); }
if (view.getBoxThemeDecks().isSelected()) { allowedDeckTypes.add(DeckType.THEME_DECK); }
if (view.getBoxUserDecks().isSelected()) { allowedDeckTypes.add(DeckType.CUSTOM_DECK); }
@@ -73,11 +78,13 @@ public enum CSubmenuGauntletQuick implements ICDoc {
final GauntletData gd = GauntletUtil.createQuickGauntlet(view.getLstDecks().getPlayer().getDeck(), view.getSliOpponents().getValue(), allowedDeckTypes);
List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
starter.add(new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()));
final List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
final RegisteredPlayer human = new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer());
starter.add(human);
starter.add(new RegisteredPlayer(gd.getDecks().get(gd.getCompleted())).setPlayer(GamePlayerUtil.createAiPlayer()));
MatchUtil.startMatch(GameType.Gauntlet, starter);
final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch();
hostedMatch.startMatch(GameType.Gauntlet, null, starter, human, GuiBase.getInterface().getNewGuiGame());
}
/* (non-Javadoc)

View File

@@ -40,7 +40,7 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
private final JPanel pnlStrut = new JPanel();
private final JPanel pnlDirections = new JPanel();
private final FDeckChooser lstLeft = new FDeckChooser(false);
private final FDeckChooser lstLeft = new FDeckChooser(null, false);
private final JList<String> lstRight = new FList<String>();
private final FScrollPane scrRight = new FScrollPane(lstRight, true,

View File

@@ -42,7 +42,7 @@ public enum VSubmenuGauntletContests implements IVSubmenu<CSubmenuGauntletContes
private final SkinnedPanel pnlLoad = new SkinnedPanel(new MigLayout("insets 0, gap 0, wrap"));
private final ContestGauntletLister gauntletList = new ContestGauntletLister();
private final FDeckChooser lstDecks = new FDeckChooser(false);
private final FDeckChooser lstDecks = new FDeckChooser(null, false);
private final FScrollPane scrLeft = new FScrollPane(gauntletList, false,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

View File

@@ -53,7 +53,7 @@ public enum VSubmenuGauntletQuick implements IVSubmenu<CSubmenuGauntletQuick> {
private final JCheckBox boxColorDecks = new FCheckBox(DeckType.COLOR_DECK.toString());
private final JCheckBox boxThemeDecks = new FCheckBox(DeckType.THEME_DECK.toString());
private final FDeckChooser lstDecks = new FDeckChooser(false);
private final FDeckChooser lstDecks = new FDeckChooser(null, false);
private final FLabel lblOptions = new FLabel.Builder().fontSize(16)
.fontStyle(Font.BOLD).text("OPTIONS").fontAlign(SwingConstants.CENTER).build();

View File

@@ -4,6 +4,7 @@ import forge.UiCommand;
import forge.gui.framework.ICDoc;
import forge.menus.IMenuProvider;
import forge.menus.MenuUtil;
import javax.swing.*;
import java.util.ArrayList;
@@ -26,6 +27,10 @@ public enum CSubmenuOnlineLobby implements ICDoc, IMenuProvider {
});
}
@Override
public void register() {
}
@Override
public void initialize() {
}

View File

@@ -32,6 +32,10 @@ public enum CSubmenuChallenges implements ICDoc {
/** */
SINGLETON_INSTANCE;
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#initialize()
*/

View File

@@ -26,6 +26,10 @@ public enum CSubmenuDuels implements ICDoc {
/** */
SINGLETON_INSTANCE;
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#initialize()
*/

View File

@@ -45,6 +45,10 @@ public enum CSubmenuQuestData implements ICDoc {
private final UiCommand cmdQuestUpdate = new UiCommand() { @Override
public void run() { update(); } };
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/

View File

@@ -48,6 +48,10 @@ public enum CSubmenuQuestDecks implements ICDoc {
}
};
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/

View File

@@ -13,6 +13,7 @@ import forge.gui.GuiChoose;
import forge.gui.framework.EDocID;
import forge.gui.framework.FScreen;
import forge.gui.framework.ICDoc;
import forge.interfaces.IGuiGame;
import forge.item.BoosterPack;
import forge.item.PaperCard;
import forge.itemmanager.DeckManager;
@@ -38,6 +39,7 @@ import forge.toolbox.FSkin.SkinImage;
import forge.toolbox.JXButtonPanel;
import javax.swing.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
@@ -56,6 +58,11 @@ public enum CSubmenuQuestDraft implements ICDoc {
private static final DecimalFormat NUMBER_FORMATTER = new DecimalFormat("#,###");
private boolean drafting = false;
private IGuiGame gui = null;
@Override
public void register() {
}
@SuppressWarnings("serial")
@Override
@@ -333,7 +340,7 @@ public enum CSubmenuQuestDraft implements ICDoc {
view.setMode(Mode.TOURNAMENT_ACTIVE);
}
QuestDraftUtils.update();
QuestDraftUtils.update(gui);
switch (view.getMode()) {
@@ -489,7 +496,7 @@ public enum CSubmenuQuestDraft implements ICDoc {
}
private void editDeck() {
VCurrentDeck.SINGLETON_INSTANCE.setItemManager(new DeckManager(GameType.Draft));
VCurrentDeck.SINGLETON_INSTANCE.setItemManager(new DeckManager(GameType.Draft, null));
Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_QUEST_TOURNAMENT);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorQuestLimited(FModel.getQuest()));
FModel.getQuest().save();
@@ -550,14 +557,15 @@ public enum CSubmenuQuestDraft implements ICDoc {
private void startNextMatch() {
String message = QuestDraftUtils.getDeckLegality();
final String message = QuestDraftUtils.getDeckLegality();
if (message != null) {
FOptionPane.showMessageDialog(message, "Deck Invalid");
return;
}
QuestDraftUtils.startNextMatch();
gui = GuiBase.getInterface().getNewGuiGame();
QuestDraftUtils.startNextMatch(gui);
}

View File

@@ -18,6 +18,10 @@ public enum CSubmenuQuestPrefs implements ICDoc {
/** */
SINGLETON_INSTANCE;
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/

View File

@@ -36,7 +36,7 @@ public enum VSubmenuQuestDecks implements IVSubmenu<CSubmenuQuestDecks> {
/** */
private final LblHeader lblTitle = new LblHeader("Quest Decks");
private final DeckManager lstDecks = new DeckManager(GameType.Quest);
private final DeckManager lstDecks = new DeckManager(GameType.Quest, null);
private final FLabel lblInfo = new FLabel.Builder()
.fontAlign(SwingConstants.LEFT).fontSize(16).fontStyle(Font.BOLD)

View File

@@ -1,5 +1,6 @@
package forge.screens.home.sanctioned;
import forge.GuiBase;
import forge.LobbyPlayer;
import forge.UiCommand;
import forge.deck.CardPool;
@@ -12,8 +13,9 @@ import forge.game.GameType;
import forge.game.player.RegisteredPlayer;
import forge.gui.GuiDialog;
import forge.gui.framework.ICDoc;
import forge.interfaces.IGuiGame;
import forge.item.PaperCard;
import forge.match.MatchUtil;
import forge.match.HostedMatch;
import forge.menus.IMenuProvider;
import forge.menus.MenuUtil;
import forge.model.CardCollections;
@@ -28,10 +30,13 @@ import forge.util.storage.IStorage;
import javax.swing.*;
import com.beust.jcommander.internal.Maps;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
@@ -49,6 +54,10 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
private final VSubmenuConstructed view = VSubmenuConstructed.SINGLETON_INSTANCE;
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.home.ICSubmenu#initialize()
*/
@@ -226,10 +235,13 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
}
}
List<RegisteredPlayer> players = new ArrayList<RegisteredPlayer>();
final List<RegisteredPlayer> players = new ArrayList<RegisteredPlayer>();
final Map<RegisteredPlayer, IGuiGame> guis = Maps.newHashMap();
final IGuiGame gui = GuiBase.getInterface().getNewGuiGame();
for (final int i : view.getParticipants()) {
String name = view.getPlayerName(i);
LobbyPlayer lobbyPlayer = view.isPlayerAI(i)
final String name = view.getPlayerName(i);
final boolean isAI = view.isPlayerAI(i);
final LobbyPlayer lobbyPlayer = isAI
? GamePlayerUtil.createAiPlayer(name, view.getPlayerAvatar(i), view.getAiOptions(i))
: GamePlayerUtil.getGuiPlayer(name, i);
RegisteredPlayer rp = view.getDeckChooser(i).getPlayer();
@@ -237,25 +249,23 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
if (variantTypes.isEmpty()) {
rp.setTeamNumber(view.getTeam(i));
players.add(rp.setPlayer(lobbyPlayer));
}
else {
} else {
Deck deck = null;
PaperCard vanguardAvatar = null;
if (isCommanderMatch) {
Object selected = view.getCommanderDeckLists().get(i).getSelectedValue();
final Object selected = view.getCommanderDeckLists().get(i).getSelectedValue();
if (selected instanceof String) {
String sel = (String) selected;
IStorage<Deck> comDecks = FModel.getDecks().getCommander();
final String sel = (String) selected;
final IStorage<Deck> comDecks = FModel.getDecks().getCommander();
if (sel.equals("Random") && comDecks.size() > 0) {
deck = Aggregates.random(comDecks);
}
}
else {
} else {
deck = (Deck) selected;
}
GameType commanderGameType = isTinyLeadersMatch ? GameType.TinyLeaders : GameType.Commander;
if (deck == null) { //Can be null if player deselects the list selection or chose Generate
deck = DeckgenUtil.generateCommanderDeck(view.isPlayerAI(i), commanderGameType);
deck = DeckgenUtil.generateCommanderDeck(isAI, commanderGameType);
}
if (checkLegality) {
String errMsg = commanderGameType.getDeckFormat().getDeckConformanceProblem(deck);
@@ -264,8 +274,7 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
return;
}
}
}
else if (autoGenerateVariant != null) {
} else if (autoGenerateVariant != null) {
deck = autoGenerateVariant.autoGenerateDeck(rp);
CardPool avatarPool = deck.get(DeckSection.Avatar);
if (avatarPool != null) {
@@ -276,7 +285,7 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
// Initialise variables for other variants
deck = deck == null ? rp.getDeck() : deck;
Iterable<PaperCard> schemes = null;
boolean playerIsArchenemy = view.isPlayerArchenemy(i);
final boolean playerIsArchenemy = view.isPlayerArchenemy(i);
Iterable<PaperCard> planes = null;
//Archenemy
@@ -354,10 +363,10 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
if (sel.contains("Use deck's default avatar") && deck.has(DeckSection.Avatar)) {
vanguardAvatar = deck.get(DeckSection.Avatar).get(0);
} else { //Only other string is "Random"
if (!view.isPlayerAI(i)) { //Human
vanguardAvatar = Aggregates.random(view.getNonRandomHumanAvatars());
} else { //AI
if (isAI) { //AI
vanguardAvatar = Aggregates.random(view.getNonRandomAiAvatars());
} else { //Human
vanguardAvatar = Aggregates.random(view.getNonRandomHumanAvatars());
}
}
} else {
@@ -374,10 +383,15 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
rp.setTeamNumber(view.getTeam(i));
players.add(rp.setPlayer(lobbyPlayer));
}
if (!isAI) {
guis.put(rp, gui);
}
view.getDeckChooser(i).saveState();
}
MatchUtil.startMatch(GameType.Constructed, variantTypes, players);
final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch();
hostedMatch.startMatch(GameType.Constructed, variantTypes, players, guis);
}
/* (non-Javadoc)

View File

@@ -1,5 +1,6 @@
package forge.screens.home.sanctioned;
import forge.GuiBase;
import forge.UiCommand;
import forge.Singletons;
import forge.deck.Deck;
@@ -14,7 +15,7 @@ import forge.gui.framework.ICDoc;
import forge.itemmanager.ItemManagerConfig;
import forge.limited.BoosterDraft;
import forge.limited.LimitedPoolType;
import forge.match.MatchUtil;
import forge.match.HostedMatch;
import forge.model.FModel;
import forge.player.GamePlayerUtil;
import forge.properties.ForgePreferences.FPref;
@@ -47,6 +48,10 @@ public enum CSubmenuDraft implements ICDoc {
}
};
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/
@@ -131,20 +136,22 @@ public enum CSubmenuDraft implements ICDoc {
}
});
DeckGroup opponentDecks = FModel.getDecks().getDraft().get(humanDeck.getName());
Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex);
final DeckGroup opponentDecks = FModel.getDecks().getDraft().get(humanDeck.getName());
final Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex);
if (aiDeck == null) {
throw new IllegalStateException("Draft: Computer deck is null!");
}
List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
starter.add(new RegisteredPlayer(humanDeck.getDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()));
final List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
final RegisteredPlayer human = new RegisteredPlayer(humanDeck.getDeck()).setPlayer(GamePlayerUtil.getGuiPlayer());
starter.add(human);
starter.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer()));
for (RegisteredPlayer pl : starter) {
pl.assignConspiracies();
}
MatchUtil.startMatch(GameType.Draft, starter);
final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch();
hostedMatch.startMatch(GameType.Draft, null, starter, human, GuiBase.getInterface().getNewGuiGame());
}
/** */

View File

@@ -40,6 +40,10 @@ public enum CSubmenuSealed implements ICDoc {
}
};
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/

View File

@@ -1,5 +1,6 @@
package forge.screens.home.sanctioned;
import forge.GuiBase;
import forge.UiCommand;
import forge.Singletons;
import forge.deck.Deck;
@@ -8,7 +9,7 @@ import forge.game.GameType;
import forge.game.player.RegisteredPlayer;
import forge.gui.GuiChoose;
import forge.gui.SOverlayUtils;
import forge.match.MatchUtil;
import forge.match.HostedMatch;
import forge.model.FModel;
import forge.screens.deckeditor.CDeckEditorUI;
import forge.deck.DeckProxy;
@@ -47,6 +48,10 @@ public enum CSubmenuWinston implements ICDoc {
}
};
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/
@@ -122,17 +127,19 @@ public enum CSubmenuWinston implements ICDoc {
}
});
DeckGroup opponentDecks = FModel.getDecks().getWinston().get(humanDeck.getName());
Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex);
final DeckGroup opponentDecks = FModel.getDecks().getWinston().get(humanDeck.getName());
final Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex);
if (aiDeck == null) {
throw new IllegalStateException("Draft: Computer deck is null!");
}
List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
starter.add(new RegisteredPlayer(humanDeck.getDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()));
final List<RegisteredPlayer> starter = new ArrayList<RegisteredPlayer>();
final RegisteredPlayer human = new RegisteredPlayer(humanDeck.getDeck()).setPlayer(GamePlayerUtil.getGuiPlayer());
starter.add(human);
starter.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer()));
MatchUtil.startMatch(GameType.Winston, starter);
final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch();
hostedMatch.startMatch(GameType.Winston, null, starter, human, GuiBase.getInterface().getNewGuiGame());
}
/** */

View File

@@ -286,7 +286,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
String labelConstraints = "gaptop 10px, gapbottom 5px";
// Main deck
final FDeckChooser mainChooser = new FDeckChooser(isPlayerAI(playerIndex));
final FDeckChooser mainChooser = new FDeckChooser(null, isPlayerAI(playerIndex));
mainChooser.initialize();
mainChooser.getLstDecks().setSelectCommand(new UiCommand() {
@Override

View File

@@ -34,7 +34,7 @@ public enum VSubmenuDraft implements IVSubmenu<CSubmenuDraft> {
private final JPanel pnlStart = new JPanel();
private final StartButton btnStart = new StartButton();
private final DeckManager lstDecks = new DeckManager(GameType.Draft);
private final DeckManager lstDecks = new DeckManager(GameType.Draft, null);
private final JRadioButton radSingle = new FRadioButton("Play one opponent");
private final JRadioButton radAll = new FRadioButton("Play all 7 opponents");
@@ -66,7 +66,7 @@ public enum VSubmenuDraft implements IVSubmenu<CSubmenuDraft> {
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
lstDecks.setCaption("Draft Decks");
JXButtonPanel grpPanel = new JXButtonPanel();
final JXButtonPanel grpPanel = new JXButtonPanel();
grpPanel.add(radSingle, "w 200px!, h 30px!");
grpPanel.add(radAll, "w 200px!, h 30px!");
radSingle.setSelected(true);

View File

@@ -44,7 +44,7 @@ public enum VSubmenuSealed implements IVSubmenu<CSubmenuSealed> {
private final LblHeader lblTitle = new LblHeader("Sanctioned Format: Sealed Deck");
private final StartButton btnStart = new StartButton();
private final DeckManager lstDecks = new DeckManager(GameType.Sealed);
private final DeckManager lstDecks = new DeckManager(GameType.Sealed, null);
private final FLabel lblInfo = new FLabel.Builder()
.fontAlign(SwingConstants.LEFT).fontSize(16).fontStyle(Font.BOLD)

View File

@@ -34,7 +34,7 @@ public enum VSubmenuWinston implements IVSubmenu<CSubmenuWinston> {
private final JPanel pnlStart = new JPanel();
private final StartButton btnStart = new StartButton();
private final DeckManager lstDecks = new DeckManager(GameType.Winston);
private final DeckManager lstDecks = new DeckManager(GameType.Winston, null);
private final JList<String> lstAI = new FList<String>();
private final JLabel lblInfo = new FLabel.Builder()

View File

@@ -20,6 +20,10 @@ public enum CSubmenuAchievements implements ICDoc {
public void initialize() {
}
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/

View File

@@ -13,6 +13,10 @@ public enum CSubmenuAvatars implements ICDoc {
private final VSubmenuAvatars view = VSubmenuAvatars.SINGLETON_INSTANCE;
@Override
public void register() {
}
@Override
public void initialize() {
}

View File

@@ -40,6 +40,10 @@ public enum CSubmenuDownloaders implements ICDoc {
public void run() { BugReporter.reportBug(null); }
};
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/

View File

@@ -47,6 +47,10 @@ public enum CSubmenuPreferences implements ICDoc {
private final List<Pair<JCheckBox, FPref>> lstControls = new ArrayList<Pair<JCheckBox,FPref>>();
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/
@@ -105,6 +109,7 @@ public enum CSubmenuPreferences implements ICDoc {
lstControls.add(Pair.of(view.getCbCompactMainMenu(), FPref.UI_COMPACT_MAIN_MENU));
lstControls.add(Pair.of(view.getCbPromptFreeBlocks(), FPref.MATCHPREF_PROMPT_FREE_BLOCKS));
lstControls.add(Pair.of(view.getCbPauseWhileMinimized(), FPref.UI_PAUSE_WHILE_MINIMIZED));
lstControls.add(Pair.of(view.getCbWorkshopSyntax(), FPref.DEV_WORKSHOP_SYNTAX));
lstControls.add(Pair.of(view.getCbCompactPrompt(), FPref.UI_COMPACT_PROMPT));
lstControls.add(Pair.of(view.getCbHideReminderText(), FPref.UI_HIDE_REMINDER_TEXT));
@@ -250,7 +255,7 @@ public enum CSubmenuPreferences implements ICDoc {
"the Dock tab -> Save Layout option in the Match screen.\n\n" +
"Reset layout?";
if (FOptionPane.showConfirmDialog(userPrompt, "Reset Match Screen Layout")) {
if (FScreen.MATCH_SCREEN.deleteLayoutFile()) {
if (FScreen.deleteMatchLayoutFile()) {
FOptionPane.showMessageDialog("Match Screen layout has been reset.");
}
}

View File

@@ -37,6 +37,10 @@ public enum CSubmenuReleaseNotes implements ICDoc {
//private ForgePreferences prefs;
private boolean isReleaseNotesUpdated = false;
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/

View File

@@ -1,6 +1,27 @@
package forge.screens.home.settings;
import forge.Singletons;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.StringUtils;
import forge.control.FControl.CloseAction;
import forge.control.KeyboardShortcuts;
import forge.control.KeyboardShortcuts.Shortcut;
@@ -13,22 +34,13 @@ import forge.properties.ForgePreferences.FPref;
import forge.screens.home.EMenuGroup;
import forge.screens.home.IVSubmenu;
import forge.screens.home.VHomeUI;
import forge.toolbox.*;
import forge.toolbox.FCheckBox;
import forge.toolbox.FComboBoxPanel;
import forge.toolbox.FLabel;
import forge.toolbox.FScrollPane;
import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinnedLabel;
import forge.toolbox.FSkin.SkinnedTextField;
import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.StringUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.*;
import java.util.List;
/**
* Assembles Swing components of preferences submenu singleton.
@@ -66,6 +78,7 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
private final JCheckBox cbManaBurn = new OptionsCheckBox("Mana Burn");
private final JCheckBox cbManaLostPrompt = new OptionsCheckBox("Prompt Mana Pool Emptying");
private final JCheckBox cbDevMode = new OptionsCheckBox("Developer Mode");
private final JCheckBox cbWorkshopSyntax = new OptionsCheckBox("Workshop Syntax Checker");
private final JCheckBox cbEnforceDeckLegality = new OptionsCheckBox("Deck Conformance");
private final JCheckBox cbCloneImgSource = new OptionsCheckBox("Clones Use Original Card Art");
private final JCheckBox cbScaleLarger = new OptionsCheckBox("Scale Image Larger");
@@ -181,6 +194,9 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
pnlPrefs.add(cbDevMode, regularConstraints);
pnlPrefs.add(new NoteLabel("Enables menu with functions for testing during development."), regularConstraints);
pnlPrefs.add(cbWorkshopSyntax, regularConstraints);
pnlPrefs.add(new NoteLabel("Enables syntax checking of card scripts in the Workshop. Note: functionality still in testing phase!"), regularConstraints);
pnlPrefs.add(cbpGameLogEntryType, "w 80%!, gap 10% 0 0 10px, span 2 1");
pnlPrefs.add(new NoteLabel("Changes how much information is displayed in the game log. Sorted by least to most verbose."), regularConstraints);
@@ -240,7 +256,7 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
final JLabel lblShortcuts = new SectionLabel("Keyboard Shortcuts");
pnlPrefs.add(lblShortcuts, sectionConstraints + ", gaptop 2%");
final List<Shortcut> shortcuts = Singletons.getControl().getShortcuts();
final List<Shortcut> shortcuts = KeyboardShortcuts.getKeyboardShortcuts();
for (final Shortcut s : shortcuts) {
pnlPrefs.add(new FLabel.Builder().text(s.getDescription())
@@ -486,6 +502,10 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
return cbDevMode;
}
public JCheckBox getCbWorkshopSyntax() {
return cbWorkshopSyntax;
}
public FComboBoxPanel<String> getAiProfilesComboBoxPanel() {
return cbpAiProfiles;
}

View File

@@ -21,9 +21,13 @@ import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;
@@ -32,21 +36,30 @@ import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.SwingUtilities;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import forge.FThreads;
import forge.ImageCache;
import forge.LobbyPlayer;
import forge.Singletons;
import forge.UiCommand;
import forge.game.Game;
import forge.assets.FSkinProp;
import forge.control.KeyboardShortcuts;
import forge.deck.CardPool;
import forge.deck.Deck;
import forge.deckchooser.FDeckViewer;
import forge.game.GameEntity;
import forge.game.GameEntityView;
import forge.game.GameView;
import forge.game.Match;
import forge.game.card.CardView;
import forge.game.combat.CombatView;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.player.DelayedReveal;
import forge.game.player.IHasIcon;
import forge.game.player.PlayerView;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
@@ -62,33 +75,38 @@ import forge.gui.framework.SDisplayUtil;
import forge.gui.framework.SLayoutIO;
import forge.interfaces.IButton;
import forge.item.InventoryItem;
import forge.match.IMatchController;
import forge.match.MatchUtil;
import forge.item.PaperCard;
import forge.match.AbstractGuiGame;
import forge.menus.IMenuProvider;
import forge.model.FModel;
import forge.player.PlayerControllerHuman;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
import forge.screens.match.controllers.CAntes;
import forge.screens.match.controllers.CCombat;
import forge.screens.match.controllers.CDetail;
import forge.screens.match.controllers.CDetailPicture;
import forge.screens.match.controllers.CDev;
import forge.screens.match.controllers.CDock;
import forge.screens.match.controllers.CLog;
import forge.screens.match.controllers.CPicture;
import forge.screens.match.controllers.CPlayers;
import forge.screens.match.controllers.CPrompt;
import forge.screens.match.controllers.CStack;
import forge.screens.match.menus.CMatchUIMenus;
import forge.screens.match.views.VCommand;
import forge.screens.match.views.VField;
import forge.screens.match.views.VHand;
import forge.screens.match.views.VPlayers;
import forge.screens.match.views.VPrompt;
import forge.toolbox.FButton;
import forge.toolbox.FOptionPane;
import forge.toolbox.FSkin;
import forge.toolbox.MouseTriggerEvent;
import forge.toolbox.FSkin.SkinImage;
import forge.toolbox.MouseTriggerEvent;
import forge.toolbox.special.PhaseIndicator;
import forge.toolbox.special.PhaseLabel;
import forge.util.FCollectionView;
import forge.util.ITriggerEvent;
import forge.util.gui.SGuiChoose;
import forge.util.gui.SOptionPane;
import forge.view.FView;
import forge.view.arcane.CardPanel;
import forge.view.arcane.FloatingCardArea;
@@ -100,16 +118,118 @@ import forge.view.arcane.FloatingCardArea;
*
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
*/
public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
SINGLETON_INSTANCE;
public final class CMatchUI
extends AbstractGuiGame
implements ICDoc, IMenuProvider {
private List<PlayerView> sortedPlayers;
private final FScreen screen;
private FCollectionView<PlayerView> sortedPlayers;
/** Players attached to this UI */
private VMatchUI view;
private boolean allHands;
private boolean showOverlay = true;
private IVDoc<? extends ICDoc> selectedDocBeforeCombat;
public final Map<String, String> avatarImages = new HashMap<String, String>();
private final CAntes cAntes = new CAntes(this);
private final CCombat cCombat = new CCombat();
private final CDetailPicture cDetailPicture = new CDetailPicture(this);
private final CDev cDev = new CDev(this);
private final CDock cDock = new CDock(this);
private final CLog cLog = new CLog(this);
private final CPlayers cPlayers = new CPlayers(this);
private final CPrompt cPrompt = new CPrompt(this);
private final CStack cStack = new CStack(this);
private final TargetingOverlay targetingOverlay = new TargetingOverlay(this);
private final Map<EDocID, IVDoc<? extends ICDoc>> myDocs;
public CMatchUI() {
this.view = new VMatchUI(this);
this.screen = FScreen.getMatchScreen(this, view);
Singletons.getView().getLpnDocument().add(targetingOverlay.getPanel(), FView.TARGETING_LAYER);
targetingOverlay.getPanel().setSize(Singletons.getControl().getDisplaySize());
this.myDocs = new EnumMap<EDocID, IVDoc<? extends ICDoc>>(EDocID.class);
this.myDocs.put(EDocID.CARD_PICTURE, getCDetailPicture().getCPicture().getView());
this.myDocs.put(EDocID.CARD_DETAIL, getCDetailPicture().getCDetail().getView());
this.myDocs.put(EDocID.CARD_ANTES, getCAntes().getView());
this.myDocs.put(EDocID.REPORT_MESSAGE, getCPrompt().getView());
this.myDocs.put(EDocID.REPORT_STACK, getCStack().getView());
this.myDocs.put(EDocID.REPORT_COMBAT, getCCombat().getView());
this.myDocs.put(EDocID.REPORT_LOG, getCLog().getView());
this.myDocs.put(EDocID.REPORT_PLAYERS, getCPlayers().getView());
this.myDocs.put(EDocID.DEV_MODE, getCDev().getView());
this.myDocs.put(EDocID.BUTTON_DOCK, getCDock().getView());;
}
private void registerDocs() {
for (final Entry<EDocID, IVDoc<? extends ICDoc>> doc : myDocs.entrySet()) {
doc.getKey().setDoc(doc.getValue());
}
}
public boolean isCurrentScreen() {
return Singletons.getControl().getCurrentScreen() == this.screen;
}
private boolean isInGame() {
return getGameView() != null;
}
@Override
public void setGameView(final GameView gameView) {
super.setGameView(gameView);
screen.setTabCaption(gameView.getTitle());
}
@Override
protected void updateCurrentPlayer(final PlayerView player) {
// No action necessary
}
public CAntes getCAntes() {
return cAntes;
}
public CCombat getCCombat() {
return cCombat;
}
public CDetailPicture getCDetailPicture() {
return cDetailPicture;
}
public CDev getCDev() {
return cDev;
}
public CDock getCDock() {
return cDock;
}
public CLog getCLog() {
return cLog;
}
public CPlayers getCPlayers() {
return cPlayers;
}
public CPrompt getCPrompt() {
return cPrompt;
}
public CStack getCStack() {
return cStack;
}
public TargetingOverlay getTargetingOverlay() {
return targetingOverlay;
}
/**
* View deck list.
*/
public void viewDeckList() {
if (!isInGame()) {
return;
}
final Deck deck = getGameView().getDeck(getCurrentPlayer().getLobbyPlayerName());
if (deck != null) {
FDeckViewer.show(deck);
}
}
private SkinImage getPlayerAvatar(final PlayerView p, final int defaultIndex) {
if (avatarImages.containsKey(p.getLobbyPlayerName())) {
@@ -125,11 +245,10 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
view.getLblAvatar().getResizeTimer().start();
}
public void initMatch(final List<PlayerView> sortedPlayers0, final boolean allHands0) {
sortedPlayers = sortedPlayers0;
allHands = allHands0;
view = VMatchUI.SINGLETON_INSTANCE;
// TODO fix for use with multiplayer
public void initMatch(final FCollectionView<PlayerView> sortedPlayers, final FCollectionView<PlayerView> myPlayers) {
this.sortedPlayers = sortedPlayers;
this.setLocalPlayers(myPlayers);
allHands = sortedPlayers.size() == getLocalPlayerCount();
final String[] indices = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",");
@@ -140,10 +259,15 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
for (final PlayerView p : sortedPlayers) {
// A field must be initialized after it's instantiated, to update player info.
// No player, no init.
VField f = new VField(EDocID.Fields[i], p);
VCommand c = new VCommand(EDocID.Commands[i], p);
final EDocID fieldDoc = EDocID.Fields[i];
final VField f = new VField(this, fieldDoc, p);
fields.add(f);
myDocs.put(fieldDoc, f);
final EDocID commandDoc = EDocID.Commands[i];
final VCommand c = new VCommand(this, commandDoc, p);
commands.add(c);
myDocs.put(commandDoc, c);
//setAvatar(f, new ImageIcon(FSkin.getAvatars().get()));
setAvatar(f, getPlayerAvatar(p, Integer.parseInt(indices[i > 2 ? 1 : 0])));
@@ -152,24 +276,26 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
i++;
}
// Replace old instances
view.setCommandViews(commands);
view.setFieldViews(fields);
VPlayers.SINGLETON_INSTANCE.init(sortedPlayers0);
getCPlayers().getView().init(this.sortedPlayers);
initHandViews();
registerDocs();
}
public void initHandViews() {
private void initHandViews() {
final List<VHand> hands = new ArrayList<VHand>();
int i = 0;
for (final PlayerView p : sortedPlayers) {
if (allHands || !p.isAI() || CardView.mayViewAny(p.getHand(), p)) {
VHand newHand = new VHand(EDocID.Hands[i], p);
if (allHands || isLocalPlayer(p) || CardView.mayViewAny(p.getHand(), getCurrentPlayer())) {
final EDocID doc = EDocID.Hands[i];
final VHand newHand = new VHand(this, doc, p);
newHand.getLayoutControl().initialize();
hands.add(newHand);
myDocs.put(doc, newHand);
}
i++;
}
@@ -187,23 +313,28 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
}
}
public void showMessage(final String s0) {
CPrompt.SINGLETON_INSTANCE.setMessage(s0);
public List<VField> getFieldViews() {
return view.getFieldViews();
}
public VField getFieldViewFor(final PlayerView p) {
final int idx = getPlayerIndex(p);
return idx < 0 ? null : getFieldViews().get(idx);
}
public VField getFieldViewFor(PlayerView p) {
int idx = getPlayerIndex(p);
return idx < 0 ? null :view.getFieldViews().get(idx);
public List<VCommand> getCommandViews() {
return view.getCommandViews();
}
public VCommand getCommandFor(final PlayerView p) {
final int idx = getPlayerIndex(p);
return idx < 0 ? null : getCommandViews().get(idx);
}
public VCommand getCommandFor(PlayerView p) {
int idx = getPlayerIndex(p);
return idx < 0 ? null :view.getCommandViews().get(idx);
public List<VHand> getHandViews() {
return view.getHands();
}
public VHand getHandFor(PlayerView p) {
int idx = getPlayerIndex(p);
List<VHand> allHands = view.getHands();
public VHand getHandFor(final PlayerView p) {
final int idx = getPlayerIndex(p);
final List<VHand> allHands = getHandViews();
return idx < 0 || idx >= allHands.size() ? null : allHands.get(idx);
}
@@ -215,26 +346,25 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
* @param phase &emsp; {@link java.lang.String}
* @return boolean
*/
@Override
public final boolean stopAtPhase(final PlayerView turn, final PhaseType phase) {
VField vf = getFieldViewFor(turn);
PhaseLabel label = vf.getPhaseIndicator()
.getLabelFor(phase);
final VField vf = getFieldViewFor(turn);
final PhaseLabel label = vf.getPhaseIndicator() .getLabelFor(phase);
return label == null || label.getEnabled();
}
@Override
public void setCard(final CardView c) {
this.setCard(c, false);
}
public void setCard(final CardView c, final boolean isInAltState) {
FThreads.assertExecutedByEdt(true);
CDetail.SINGLETON_INSTANCE.showCard(c, isInAltState);
CPicture.SINGLETON_INSTANCE.showCard(c, isInAltState);
cDetailPicture.showCard(c, isInAltState);
}
public void setCard(final InventoryItem c) {
CDetail.SINGLETON_INSTANCE.showCard(c);
CPicture.SINGLETON_INSTANCE.showImage(c);
public void setCard(final InventoryItem item) {
cDetailPicture.showItem(item);
}
private int getPlayerIndex(PlayerView player) {
@@ -243,8 +373,8 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
@Override
public void showCombat() {
CombatView combat = MatchUtil.getGameView().getCombat();
if (combat != null && combat.getNumAttackers() > 0 && MatchUtil.getGameView().peekStack() == null) {
final CombatView combat = getGameView().getCombat();
if (combat != null && combat.getNumAttackers() > 0 && getGameView().peekStack() == null) {
if (selectedDocBeforeCombat == null) {
IVDoc<? extends ICDoc> combatDoc = EDocID.REPORT_COMBAT.getDoc();
if (combatDoc.getParentCell() != null) {
@@ -262,22 +392,22 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
SDisplayUtil.showTab(selectedDocBeforeCombat);
selectedDocBeforeCombat = null;
}
CCombat.SINGLETON_INSTANCE.setModel(combat);
CCombat.SINGLETON_INSTANCE.update();
getCCombat().setModel(combat);
getCCombat().update();
} // showCombat(CombatView)
public void updateZones(List<Pair<PlayerView, ZoneType>> zonesToUpdate) {
//System.out.println("updateZones " + zonesToUpdate);
for (Pair<PlayerView, ZoneType> kv : zonesToUpdate) {
PlayerView owner = kv.getKey();
ZoneType zt = kv.getValue();
@Override
public void updateZones(final List<Pair<PlayerView, ZoneType>> zonesToUpdate) {
for (final Pair<PlayerView, ZoneType> kv : zonesToUpdate) {
final PlayerView owner = kv.getKey();
final ZoneType zt = kv.getValue();
switch (zt) {
case Battlefield:
getFieldViewFor(owner).getTabletop().setupPlayZone();
break;
case Hand:
VHand vHand = getHandFor(owner);
final VHand vHand = getHandFor(owner);
if (vHand != null) {
vHand.getLayoutControl().updateHand();
}
@@ -288,7 +418,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
getCommandFor(owner).getTabletop().setupPlayZone();
break;
case Ante:
CAntes.SINGLETON_INSTANCE.update();
cAntes.update();
break;
default:
final VField vf = getFieldViewFor(owner);
@@ -302,6 +432,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
}
// Player's mana pool changes
@Override
public void updateManaPool(final Iterable<PlayerView> manaPoolUpdate) {
for (final PlayerView p : manaPoolUpdate) {
getFieldViewFor(p).getDetailsPanel().updateManaPool();
@@ -310,19 +441,21 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
}
// Player's lives and poison counters
@Override
public void updateLives(final Iterable<PlayerView> livesUpdate) {
for (final PlayerView p : livesUpdate) {
getFieldViewFor(p).updateDetails();
}
}
@Override
public void updateSingleCard(final CardView c) {
ZoneType zone = c.getZone();
final ZoneType zone = c.getZone();
if (zone == null) { return; }
switch (zone) {
case Battlefield:
VField battlefield = getFieldViewFor(c.getController());
final VField battlefield = getFieldViewFor(c.getController());
if (battlefield != null) {
battlefield.getTabletop().updateCard(c, false);
}
@@ -337,7 +470,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
}
break;
case Command:
VCommand command = getCommandFor(c.getController());
final VCommand command = getCommandFor(c.getController());
if (command != null) {
command.getTabletop().updateCard(c, false);
}
@@ -347,15 +480,9 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
}
}
public void refreshCardDetails(final Iterable<CardView> cards) {
for (final CardView c : cards) {
updateSingleCard(c);
}
}
@Override
public List<JMenu> getMenus() {
return new CMatchUIMenus().getMenus();
return new CMatchUIMenus(this).getMenus(cDev);
}
@Override
@@ -364,28 +491,42 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
}
@Override
public void initialize() {
Singletons.getControl().getForgeMenu().setProvider(this);
public void register() {
initHandViews();
registerDocs();
}
@Override
public void update() { }
public void initialize() {
Singletons.getControl().getForgeMenu().setProvider(this);
updatePlayerControl();
KeyboardShortcuts.attachKeyboardShortcuts(this);
for (final IVDoc<? extends ICDoc> view : myDocs.values()) {
final ICDoc layoutControl = view.getLayoutControl();
layoutControl.initialize();
layoutControl.update();
}
}
@Override
public void update() {
}
public void repaintCardOverlays() {
List<CardPanel> panels = getVisibleCardPanels();
for (CardPanel panel : panels) {
final List<CardPanel> panels = getVisibleCardPanels();
for (final CardPanel panel : panels) {
panel.repaintOverlays();
}
}
private List<CardPanel> getVisibleCardPanels() {
List<CardPanel> panels = new ArrayList<CardPanel>();
for (VHand h : view.getHands()) {
final List<CardPanel> panels = new ArrayList<CardPanel>();
for (final VHand h : view.getHands()) {
panels.addAll(h.getHandArea().getCardPanels());
}
for (VField f : view.getFieldViews()) {
for (final VField f : view.getFieldViews()) {
panels.addAll(f.getTabletop().getCardPanels());
}
for (VCommand c : view.getCommandViews()) {
for (final VCommand c : view.getCommandViews()) {
panels.addAll(c.getTabletop().getCardPanels());
}
return panels;
@@ -393,28 +534,17 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
@Override
public boolean resetForNewGame() {
if (MatchUtil.getGame() != null) {
Singletons.getControl().setCurrentScreen(FScreen.MATCH_SCREEN);
SOverlayUtils.hideOverlay();
FOptionPane.showMessageDialog("Cannot start a new game while another game is already in progress.");
return false; //TODO: See if it's possible to run multiple games at once without crashing
}
return true;
}
@Override
public boolean hotSeatMode() {
return true; //Desktop game only supports hot seat mode for Human v. Human
public IButton getBtnOK(final PlayerView playerView) {
return view.getBtnOK();
}
@Override
public IButton getBtnOK(PlayerView playerView) {
return VMatchUI.SINGLETON_INSTANCE.getBtnOK();
}
@Override
public IButton getBtnCancel(PlayerView playerView) {
return VMatchUI.SINGLETON_INSTANCE.getBtnCancel();
public IButton getBtnCancel(final PlayerView playerView) {
return view.getBtnCancel();
}
@Override
@@ -432,18 +562,16 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
@Override
public void flashIncorrectAction() {
SDisplayUtil.remind(VPrompt.SINGLETON_INSTANCE);
SDisplayUtil.remind(getCPrompt().getView());
}
@Override
public void updatePhase() {
GameView gameView = MatchUtil.getGameView();
final PlayerView p = gameView.getPlayerTurn();
final PhaseType ph = gameView.getPhase();
final CMatchUI matchUi = CMatchUI.SINGLETON_INSTANCE;
PhaseLabel lbl = matchUi.getFieldViewFor(p).getPhaseIndicator().getLabelFor(ph);
final PlayerView p = getGameView().getPlayerTurn();
final PhaseType ph = getGameView().getPhase();
PhaseLabel lbl = getFieldViewFor(p).getPhaseIndicator().getLabelFor(ph);
matchUi.resetAllPhaseButtons();
resetAllPhaseButtons();
if (lbl != null) {
lbl.setActive(true);
}
@@ -451,18 +579,18 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
@Override
public void updateTurn(final PlayerView player) {
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(player);
VField nextField = getFieldViewFor(player);
SDisplayUtil.showTab(nextField);
CPrompt.SINGLETON_INSTANCE.updateText();
CMatchUI.SINGLETON_INSTANCE.repaintCardOverlays();
cPrompt.updateText();
repaintCardOverlays();
}
@Override
public void updatePlayerControl() {
CMatchUI.SINGLETON_INSTANCE.initHandViews();
initHandViews();
SLayoutIO.loadLayout(null);
VMatchUI.SINGLETON_INSTANCE.populate();
for (VHand h : VMatchUI.SINGLETON_INSTANCE.getHands()) {
view.populate();
for (final VHand h : getHandViews()) {
h.getLayoutControl().updateHand();
}
}
@@ -480,7 +608,9 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
@Override
public void finishGame() {
FloatingCardArea.closeAll(); //ensure floating card areas cleared and closed after the game
new ViewWinLose(MatchUtil.getGameView());
if (hasLocalPlayers() || getGameView().isMatchOver()) {
new ViewWinLose(getGameView(), this);
}
if (showOverlay) {
SOverlayUtils.showOverlay();
}
@@ -488,12 +618,38 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
@Override
public void updateStack() {
CStack.SINGLETON_INSTANCE.update();
getCStack().update();
}
/**
* Clear all visually highlighted card panels on the battlefield.
*/
public void clearPanelSelections() {
final List<VField> fields = view.getFieldViews();
for (final VField field : fields) {
for (final CardPanel p : field.getTabletop().getCardPanels()) {
p.setSelected(false);
}
}
}
/**
* Highlight a card on the playfield.
*
* @param card
* a card to be highlighted
*/
@Override
public void setPanelSelection(final CardView c) {
GuiUtils.setPanelSelection(c);
public void setPanelSelection(final CardView card) {
for (final VField v : view.getFieldViews()) {
final List<CardPanel> panels = v.getTabletop().getCardPanels();
for (final CardPanel p : panels) {
if (p.getCard().equals(card)) {
p.setSelected(true);
return;
}
}
}
}
@Override
@@ -534,7 +690,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
new Runnable() {
@Override
public void run() {
CPrompt.SINGLETON_INSTANCE.selectAbility(ab);
cPrompt.selectAbility(ab);
}
}, enabled);
if (shortcut > 0) {
@@ -559,7 +715,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
@Override
public void showPromptMessage(final PlayerView playerView, final String message) {
CMatchUI.SINGLETON_INSTANCE.showMessage(message);
cPrompt.setMessage(message);
}
public Object showManaPool(final PlayerView player) {
@@ -571,6 +727,121 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
//not needed since mana pool icons are always visible
}
@Override
public Map<CardView, Integer> assignDamage(final CardView attacker,
final List<CardView> blockers, final int damage,
final GameEntityView defender, final boolean overrideOrder) {
if (damage <= 0) {
return Collections.emptyMap();
}
// If the first blocker can absorb all of the damage, don't show the Assign Damage dialog
final CardView firstBlocker = blockers.get(0);
if (!overrideOrder && !attacker.getCurrentState().hasDeathtouch() && firstBlocker.getLethalDamage() >= damage) {
return ImmutableMap.of(firstBlocker, damage);
}
final AtomicReference<Map<CardView, Integer>> result = new AtomicReference<Map<CardView,Integer>>();
FThreads.invokeInEdtAndWait(new Runnable() {
@Override
public void run() {
final VAssignDamage v = new VAssignDamage(CMatchUI.this, attacker, blockers, damage, defender, overrideOrder);
result.set(v.getDamageMap());
}});
return result.get();
}
@Override
public void hear(LobbyPlayer player, String message) {
FNetOverlay.SINGLETON_INSTANCE.addMessage(player.getName(), message);
}
@Override
public void openView(final FCollectionView<PlayerView> myPlayers) {
getGameView().getGameLog().addObserver(getCLog());
initMatch(getGameView().getPlayers(), myPlayers);
actuateMatchPreferences();
Singletons.getControl().setCurrentScreen(screen);
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch
//Set Field shown to current player.
//if (util.getHumanCount() > 0) {
final VField nextField = getFieldViewFor(getGameView().getPlayers().get(0));
SDisplayUtil.showTab(nextField);
//}
SOverlayUtils.hideOverlay();
}
@Override
public void afterGameEnd() {
Singletons.getView().getNavigationBar().closeTab(screen);
}
@Override
public int showOptionDialog(final String message, final String title, final FSkinProp icon, final String[] options, final int defaultOption) {
return FOptionPane.showOptionDialog(message, title, icon == null ? null : FSkin.getImage(icon), options, defaultOption);
}
@Override
public int showCardOptionDialog(final CardView card, final String message, final String title, final FSkinProp skinIcon, final String[] options, final int defaultOption) {
if (card != null) {
setCard(card);
}
return showOptionDialog(message, title, skinIcon, options, defaultOption);
}
@Override
public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final String[] inputOptions) {
return FOptionPane.showInputDialog(message, title, icon == null ? null : FSkin.getImage(icon), initialInput, inputOptions);
}
@Override
public <T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices, final T selected, final Function<T, String> display) {
/*if ((choices != null && !choices.isEmpty() && choices.iterator().next() instanceof GameObject) || selected instanceof GameObject) {
System.err.println("Warning: GameObject passed to GUI! Printing stack trace.");
Thread.dumpStack();
}*/
return GuiChoose.getChoices(message, min, max, choices, selected, display);
}
@Override
public <T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
final List<T> sourceChoices, final List<T> destChoices, final CardView referenceCard, final boolean sideboardingMode) {
/*if ((sourceChoices != null && !sourceChoices.isEmpty() && sourceChoices.iterator().next() instanceof GameObject)
|| (destChoices != null && !destChoices.isEmpty() && destChoices.iterator().next() instanceof GameObject)) {
System.err.println("Warning: GameObject passed to GUI! Printing stack trace.");
Thread.dumpStack();
}*/
return GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode);
}
@Override
public List<PaperCard> sideboard(final CardPool sideboard, final CardPool main) {
return GuiChoose.sideboard(this, sideboard.toFlatList(), main.toFlatList());
}
@Override
public GameEntityView chooseSingleEntityForEffect(final String title, final FCollectionView<? extends GameEntity> optionList, final DelayedReveal delayedReveal, final boolean isOptional, final PlayerControllerHuman controller) {
if (delayedReveal != null) {
delayedReveal.reveal(controller); //TODO: Merge this into search dialog
}
controller.tempShow(optionList);
final List<GameEntityView> gameEntityViews = GameEntityView.getEntityCollection(optionList);
if (isOptional) {
return oneOrNone(title, gameEntityViews);
}
return one(title, gameEntityViews);
}
@Override
public void setPlayerAvatar(final LobbyPlayer player, final IHasIcon ihi) {
avatarImages.put(player.getName(), ihi.getIconImageKey());
}
@Override
public boolean openZones(final Collection<ZoneType> zones, final Map<PlayerView, Object> players) {
if (zones.size() == 1) {
@@ -589,66 +860,10 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
public void restoreOldZones(final Map<PlayerView, Object> playersToRestoreZonesFor) {
}
@SuppressWarnings("unchecked")
@Override
public Map<CardView, Integer> assignDamage(final CardView attacker,
final List<CardView> blockers, final int damage,
final GameEntityView defender, final boolean overrideOrder) {
final Object[] result = { null }; // how else can I extract a value from EDT thread?
FThreads.invokeInEdtAndWait(new Runnable() {
@Override
public void run() {
VAssignDamage v = new VAssignDamage(attacker, blockers, damage, defender, overrideOrder);
result[0] = v.getDamageMap();
}});
return (Map<CardView, Integer>)result[0];
}
@Override
public void hear(LobbyPlayer player, String message) {
FNetOverlay.SINGLETON_INSTANCE.addMessage(player.getName(), message);
}
@Override
public void startNewMatch(final Match match) {
SOverlayUtils.startGameOverlay();
SOverlayUtils.showOverlay();
FThreads.invokeInEdtLater(new Runnable() {
@Override
public void run() {
MatchUtil.startGame(match);
}
});
}
@Override
public void openView(List<Player> sortedPlayers) {
Game game = MatchUtil.getGame();
game.getGameLog().addObserver(CLog.SINGLETON_INSTANCE);
List<PlayerView> sortedPlayerViews = new ArrayList<PlayerView>();
for (Player p : sortedPlayers) {
sortedPlayerViews.add(PlayerView.get(p));
}
CMatchUI.SINGLETON_INSTANCE.initMatch(sortedPlayerViews, MatchUtil.getHumanCount() != 1);
actuateMatchPreferences();
Singletons.getControl().setCurrentScreen(FScreen.MATCH_SCREEN);
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch
//Set Field shown to current player.
if (MatchUtil.getHumanCount() > 0) {
final VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(sortedPlayerViews.get(0));
SDisplayUtil.showTab(nextField);
}
SOverlayUtils.hideOverlay();
}
@Override
public void afterGameEnd() {
Singletons.getView().getNavigationBar().closeTab(FScreen.MATCH_SCREEN);
public boolean isUiSetToSkipPhase(final PlayerView playerTurn, final PhaseType phase) {
final PhaseLabel label = getFieldViewFor(playerTurn).getPhaseIndicator().getLabelFor(phase);
return label != null && !label.getEnabled();
}
/**
@@ -656,7 +871,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
*/
public void writeMatchPreferences() {
final ForgePreferences prefs = FModel.getPreferences();
final List<VField> fieldViews = VMatchUI.SINGLETON_INSTANCE.getFieldViews();
final List<VField> fieldViews = getFieldViews();
// AI field is at index [1]
PhaseIndicator fvAi = fieldViews.get(1).getPhaseIndicator();
@@ -696,7 +911,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
*/
private void actuateMatchPreferences() {
final ForgePreferences prefs = FModel.getPreferences();
final List<VField> fieldViews = VMatchUI.SINGLETON_INSTANCE.getFieldViews();
final List<VField> fieldViews = getFieldViews();
// Human field is at index [0]
PhaseIndicator fvHuman = fieldViews.get(0).getPhaseIndicator();
@@ -732,4 +947,31 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
//Singletons.getView().getViewMatch().setLayoutParams(prefs.getPref(FPref.UI_LAYOUT_PARAMS));
}
@Override
public void message(String message, String title) {
SOptionPane.showMessageDialog(message, title);
}
@Override
public void showErrorDialog(String message, String title) {
SOptionPane.showErrorDialog(message, title);
}
@Override
public boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final String[] options) {
final String title = c == null ? "Question" : c + " - Ability";
final String questionToUse = StringUtils.isBlank(question) ? "Activate card's ability?" : question;
final String[] opts = options == null ? SGuiChoose.defaultConfirmOptions : options;
final int reply = FOptionPane.showOptionDialog(questionToUse, title, FOptionPane.QUESTION_ICON, opts, defaultIsYes ? 0 : 1);
return reply == 0;
}
@Override
public boolean showConfirmDialog(final String message, final String title, final String yesButtonText, final String noButtonText, final boolean defaultYes) {
final String[] options = {yesButtonText, noButtonText};
final int reply = SOptionPane.showOptionDialog(message, title, SOptionPane.QUESTION_ICON, options, defaultYes ? 0 : 1);
return reply == 0;
}
}

View File

@@ -9,7 +9,8 @@ import forge.Singletons;
import forge.game.GameView;
import forge.gui.SOverlayUtils;
import forge.gui.framework.FScreen;
import forge.match.MatchUtil;
import forge.interfaces.IGameController;
import forge.match.NextGameDecision;
/**
* Default controller for a ViewWinLose object. This class can
@@ -20,12 +21,14 @@ import forge.match.MatchUtil;
public class ControlWinLose {
private final ViewWinLose view;
protected final GameView lastGame;
protected final CMatchUI matchUI;
/** @param v &emsp; ViewWinLose
* @param match */
public ControlWinLose(final ViewWinLose v, final GameView game0) {
public ControlWinLose(final ViewWinLose v, final GameView game0, final CMatchUI matchUI) {
this.view = v;
this.lastGame = game0;
this.matchUI = matchUI;
addListeners();
}
@@ -58,21 +61,27 @@ public class ControlWinLose {
public void actionOnContinue() {
SOverlayUtils.hideOverlay();
saveOptions();
MatchUtil.continueMatch();
for (final IGameController controller : matchUI.getGameControllers()) {
controller.nextGameDecision(NextGameDecision.CONTINUE);
}
}
/** Action performed when "restart" button is pressed in default win/lose UI. */
public void actionOnRestart() {
SOverlayUtils.hideOverlay();
saveOptions();
MatchUtil.restartMatch();
for (final IGameController controller : matchUI.getGameControllers()) {
controller.nextGameDecision(NextGameDecision.NEW);
}
}
/** Action performed when "quit" button is pressed in default win/lose UI. */
public void actionOnQuit() {
// Reset other stuff
saveOptions();
MatchUtil.endCurrentGame();
for (final IGameController controller : matchUI.getGameControllers()) {
controller.nextGameDecision(NextGameDecision.QUIT);
}
Singletons.getControl().setCurrentScreen(FScreen.HOME_SCREEN);
SOverlayUtils.hideOverlay();
}
@@ -82,7 +91,7 @@ public class ControlWinLose {
* with other game modes.
*/
public void saveOptions() {
CMatchUI.SINGLETON_INSTANCE.writeMatchPreferences();
matchUI.writeMatchPreferences();
}
/**

View File

@@ -45,8 +45,8 @@ public class GauntletWinLose extends ControlWinLose {
* @param view0 ViewWinLose object
* @param match
*/
public GauntletWinLose(final ViewWinLose view0, final GameView game0) {
super(view0, game0);
public GauntletWinLose(final ViewWinLose view0, final GameView game0, final CMatchUI matchUI) {
super(view0, game0, matchUI);
controller = new GauntletWinLoseController(view0, game0) {
@Override
protected void showOutcome(String message1, String message2, FSkinProp icon, List<String> lstEventNames, List<String> lstEventRecords, int len, int num) {

View File

@@ -46,8 +46,8 @@ public class LimitedWinLose extends ControlWinLose {
* @param view0 {@link forge.screens.match.ViewWinLose}
* @param match {@link forge.game.Match}
*/
public LimitedWinLose(final ViewWinLose view0, final GameView game0) {
super(view0, game0);
public LimitedWinLose(final ViewWinLose view0, final GameView game0, final CMatchUI matchUI) {
super(view0, game0, matchUI);
controller = new LimitedWinLoseController(view0, game0) {
@Override
protected void showOutcome(Runnable runnable) {

View File

@@ -18,6 +18,7 @@ package forge.screens.match;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import forge.LobbyPlayer;
import forge.Singletons;
import forge.assets.FSkinProp;
@@ -25,7 +26,7 @@ import forge.game.GameView;
import forge.game.player.PlayerView;
import forge.gui.SOverlayUtils;
import forge.gui.framework.FScreen;
import forge.match.MatchUtil;
import forge.match.NextGameDecision;
import forge.model.FModel;
import forge.player.GamePlayerUtil;
import forge.quest.QuestController;
@@ -48,7 +49,6 @@ import forge.toolbox.FSkin;
*/
public class QuestDraftWinLose extends ControlWinLose {
private final transient ViewWinLose view;
private final transient QuestController qData;
/**
@@ -57,8 +57,8 @@ public class QuestDraftWinLose extends ControlWinLose {
* @param view0 ViewWinLose object
* @param match2
*/
public QuestDraftWinLose(final ViewWinLose view0, final GameView game0) {
super(view0, game0);
public QuestDraftWinLose(final ViewWinLose view0, final GameView game0, final CMatchUI matchUI) {
super(view0, game0, matchUI);
this.view = view0;
qData = FModel.getQuest();
}
@@ -97,11 +97,11 @@ public class QuestDraftWinLose extends ControlWinLose {
if (lastGame.isMatchOver()) {
this.actionOnQuitMatch();
QuestDraftUtils.matchInProgress = false;
QuestDraftUtils.update();
QuestDraftUtils.update(matchUI);
}
else {
this.actionOnContinue();
QuestDraftUtils.update();
QuestDraftUtils.update(matchUI);
}
return false;
}
@@ -113,21 +113,20 @@ public class QuestDraftWinLose extends ControlWinLose {
view.getBtnQuit().setEnabled(true);
view.getBtnContinue().setEnabled(false);
view.getBtnQuit().setText("Continue Tournament");
for (ActionListener listener : view.getBtnQuit().getActionListeners()) {
for (final ActionListener listener : view.getBtnQuit().getActionListeners()) {
view.getBtnQuit().removeActionListener(listener);
}
view.getBtnQuit().addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
MatchUtil.endCurrentGame();
matchUI.getGameController().nextGameDecision(NextGameDecision.CONTINUE);
QuestDraftUtils.matchInProgress = false;
QuestDraftUtils.continueMatches();
QuestDraftUtils.continueMatches(matchUI);
}
});
}
else {
} else {
view.getBtnQuit().setEnabled(true);
for (ActionListener listener : view.getBtnQuit().getActionListeners()) {
for (final ActionListener listener : view.getBtnQuit().getActionListeners()) {
view.getBtnQuit().removeActionListener(listener);
}
view.getBtnQuit().setText("Forfeit Tournament");
@@ -135,9 +134,9 @@ public class QuestDraftWinLose extends ControlWinLose {
@Override
public void actionPerformed(final ActionEvent e) {
if (FOptionPane.showOptionDialog("Quitting the match now will forfeit the tournament!\n\nReally quit?", "Really Quit Tournament?", FSkin.getImage(FSkinProp.ICO_WARNING).scale(2), new String[] { "Yes", "No" }, 1) == 0) {
MatchUtil.endCurrentGame();
matchUI.getGameController().nextGameDecision(NextGameDecision.QUIT);
QuestDraftUtils.matchInProgress = false;
QuestDraftUtils.continueMatches();
QuestDraftUtils.continueMatches(matchUI);
}
}
});
@@ -156,9 +155,8 @@ public class QuestDraftWinLose extends ControlWinLose {
qData.setCurrentEvent(null);
qData.save();
FModel.getQuestPreferences().save();
CMatchUI.SINGLETON_INSTANCE.writeMatchPreferences();
matchUI.writeMatchPreferences();
MatchUtil.endCurrentGame();
Singletons.getControl().setCurrentScreen(FScreen.HOME_SCREEN);
SOverlayUtils.hideOverlay();

Some files were not shown because too many files have changed in this diff Show More