Holy Graphical User Interface, Batman!
42
.gitattributes
vendored
@@ -9805,6 +9805,7 @@ res/images/deckeditor/filter_sorcery_n.png -text svneol=unset#image/png
|
|||||||
res/images/deckeditor/filter_sorcery_y.png -text svneol=unset#image/png
|
res/images/deckeditor/filter_sorcery_y.png -text svneol=unset#image/png
|
||||||
res/images/deckeditor/filter_white_n.png -text svneol=unset#image/png
|
res/images/deckeditor/filter_white_n.png -text svneol=unset#image/png
|
||||||
res/images/deckeditor/filter_white_y.png -text svneol=unset#image/png
|
res/images/deckeditor/filter_white_y.png -text svneol=unset#image/png
|
||||||
|
res/images/skins/default/bg_match.jpg -text
|
||||||
res/images/skins/default/bg_splash.jpg -text
|
res/images/skins/default/bg_splash.jpg -text
|
||||||
res/images/skins/default/btnLdown.png -text
|
res/images/skins/default/btnLdown.png -text
|
||||||
res/images/skins/default/btnLover.png -text
|
res/images/skins/default/btnLover.png -text
|
||||||
@@ -9818,9 +9819,9 @@ res/images/skins/default/btnRup.png -text
|
|||||||
res/images/skins/default/font1.ttf -text
|
res/images/skins/default/font1.ttf -text
|
||||||
res/images/skins/default/font2.ttf -text
|
res/images/skins/default/font2.ttf -text
|
||||||
res/images/skins/default/palette.png -text
|
res/images/skins/default/palette.png -text
|
||||||
|
res/images/skins/default/sprite.png -text
|
||||||
res/images/skins/default/texture1.jpg -text
|
res/images/skins/default/texture1.jpg -text
|
||||||
res/images/skins/default/texture2.jpg -text
|
res/images/skins/rebel/bg_match.jpg -text
|
||||||
res/images/skins/default/texture3.jpg -text
|
|
||||||
res/images/skins/rebel/bg_splash.jpg -text
|
res/images/skins/rebel/bg_splash.jpg -text
|
||||||
res/images/skins/rebel/btnLdown.png -text
|
res/images/skins/rebel/btnLdown.png -text
|
||||||
res/images/skins/rebel/btnLover.png -text
|
res/images/skins/rebel/btnLover.png -text
|
||||||
@@ -9834,9 +9835,8 @@ res/images/skins/rebel/btnRup.png -text
|
|||||||
res/images/skins/rebel/font1.ttf -text
|
res/images/skins/rebel/font1.ttf -text
|
||||||
res/images/skins/rebel/font2.ttf -text
|
res/images/skins/rebel/font2.ttf -text
|
||||||
res/images/skins/rebel/palette.png -text
|
res/images/skins/rebel/palette.png -text
|
||||||
|
res/images/skins/rebel/sprite.png -text
|
||||||
res/images/skins/rebel/texture1.jpg -text
|
res/images/skins/rebel/texture1.jpg -text
|
||||||
res/images/skins/rebel/texture2.jpg -text
|
|
||||||
res/images/skins/rebel/texture3.jpg -text
|
|
||||||
res/images/symbols-13/0.png -text svneol=unset#image/png
|
res/images/symbols-13/0.png -text svneol=unset#image/png
|
||||||
res/images/symbols-13/1.png -text svneol=unset#image/png
|
res/images/symbols-13/1.png -text svneol=unset#image/png
|
||||||
res/images/symbols-13/10.png -text svneol=unset#image/png
|
res/images/symbols-13/10.png -text svneol=unset#image/png
|
||||||
@@ -9891,6 +9891,12 @@ res/images/symbols-13/counters2.png -text
|
|||||||
res/images/symbols-13/counters3.png -text
|
res/images/symbols-13/counters3.png -text
|
||||||
res/images/symbols-13/countersMulti.png -text
|
res/images/symbols-13/countersMulti.png -text
|
||||||
res/images/symbols-13/defend.png -text svneol=unset#image/png
|
res/images/symbols-13/defend.png -text svneol=unset#image/png
|
||||||
|
res/images/symbols-13/detail_exile.png -text
|
||||||
|
res/images/symbols-13/detail_flashback.png -text
|
||||||
|
res/images/symbols-13/detail_grave.png -text
|
||||||
|
res/images/symbols-13/detail_hand.png -text
|
||||||
|
res/images/symbols-13/detail_library.png -text
|
||||||
|
res/images/symbols-13/detail_poison.png -text
|
||||||
res/images/symbols-13/foil01.png -text svneol=unset#image/png
|
res/images/symbols-13/foil01.png -text svneol=unset#image/png
|
||||||
res/images/symbols-13/foil02.png -text svneol=unset#image/png
|
res/images/symbols-13/foil02.png -text svneol=unset#image/png
|
||||||
res/images/symbols-13/foil03.png -text svneol=unset#image/png
|
res/images/symbols-13/foil03.png -text svneol=unset#image/png
|
||||||
@@ -10692,6 +10698,18 @@ src/main/java/forge/card/trigger/TriggerTurnFaceUp.java svneol=native#text/plain
|
|||||||
src/main/java/forge/card/trigger/TriggerUnequip.java svneol=native#text/plain
|
src/main/java/forge/card/trigger/TriggerUnequip.java svneol=native#text/plain
|
||||||
src/main/java/forge/card/trigger/TriggerUntaps.java svneol=native#text/plain
|
src/main/java/forge/card/trigger/TriggerUntaps.java svneol=native#text/plain
|
||||||
src/main/java/forge/card/trigger/package-info.java svneol=native#text/plain
|
src/main/java/forge/card/trigger/package-info.java svneol=native#text/plain
|
||||||
|
src/main/java/forge/control/ControlAllUI.java -text
|
||||||
|
src/main/java/forge/control/ControlEditorUI.java -text
|
||||||
|
src/main/java/forge/control/ControlHomeUI.java -text
|
||||||
|
src/main/java/forge/control/ControlMatchUI.java -text
|
||||||
|
src/main/java/forge/control/match/ControlCardviewer.java -text
|
||||||
|
src/main/java/forge/control/match/ControlDock.java -text
|
||||||
|
src/main/java/forge/control/match/ControlField.java -text
|
||||||
|
src/main/java/forge/control/match/ControlHand.java -text
|
||||||
|
src/main/java/forge/control/match/ControlInput.java -text
|
||||||
|
src/main/java/forge/control/match/ControlTabber.java -text
|
||||||
|
src/main/java/forge/control/match/package-info.java -text
|
||||||
|
src/main/java/forge/control/package-info.java -text
|
||||||
src/main/java/forge/deck/Deck.java svneol=native#text/plain
|
src/main/java/forge/deck/Deck.java svneol=native#text/plain
|
||||||
src/main/java/forge/deck/DeckGeneration.java -text
|
src/main/java/forge/deck/DeckGeneration.java -text
|
||||||
src/main/java/forge/deck/DeckManager.java svneol=native#text/plain
|
src/main/java/forge/deck/DeckManager.java svneol=native#text/plain
|
||||||
@@ -10848,6 +10866,18 @@ src/main/java/forge/quest/gui/main/package-info.java svneol=native#text/plain
|
|||||||
src/main/java/forge/quest/gui/package-info.java svneol=native#text/plain
|
src/main/java/forge/quest/gui/package-info.java svneol=native#text/plain
|
||||||
src/main/java/forge/quest/package-info.java svneol=native#text/plain
|
src/main/java/forge/quest/package-info.java svneol=native#text/plain
|
||||||
src/main/java/forge/view/FView.java svneol=native#text/plain
|
src/main/java/forge/view/FView.java svneol=native#text/plain
|
||||||
|
src/main/java/forge/view/GuiTopLevel.java -text
|
||||||
|
src/main/java/forge/view/home/HomeTopLevel.java -text
|
||||||
|
src/main/java/forge/view/match/ViewAreaBattlefield.java -text
|
||||||
|
src/main/java/forge/view/match/ViewAreaSidebar.java -text
|
||||||
|
src/main/java/forge/view/match/ViewAreaUser.java -text
|
||||||
|
src/main/java/forge/view/match/ViewCardviewer.java -text
|
||||||
|
src/main/java/forge/view/match/ViewDock.java -text
|
||||||
|
src/main/java/forge/view/match/ViewField.java -text
|
||||||
|
src/main/java/forge/view/match/ViewHand.java -text
|
||||||
|
src/main/java/forge/view/match/ViewInput.java -text
|
||||||
|
src/main/java/forge/view/match/ViewTabber.java -text
|
||||||
|
src/main/java/forge/view/match/ViewTopLevel.java -text
|
||||||
src/main/java/forge/view/package-info.java svneol=native#text/plain
|
src/main/java/forge/view/package-info.java svneol=native#text/plain
|
||||||
src/main/java/forge/view/swing/ApplicationView.java svneol=native#text/plain
|
src/main/java/forge/view/swing/ApplicationView.java svneol=native#text/plain
|
||||||
src/main/java/forge/view/swing/GuiHomeScreen.java svneol=native#text/plain
|
src/main/java/forge/view/swing/GuiHomeScreen.java svneol=native#text/plain
|
||||||
@@ -10859,6 +10889,10 @@ src/main/java/forge/view/swing/SplashProgressModel.java -text
|
|||||||
src/main/java/forge/view/swing/WinLoseFrame.java -text
|
src/main/java/forge/view/swing/WinLoseFrame.java -text
|
||||||
src/main/java/forge/view/swing/WinLoseModeHandler.java -text
|
src/main/java/forge/view/swing/WinLoseModeHandler.java -text
|
||||||
src/main/java/forge/view/swing/package-info.java svneol=native#text/plain
|
src/main/java/forge/view/swing/package-info.java svneol=native#text/plain
|
||||||
|
src/main/java/forge/view/toolbox/CardDetailPanel.java -text
|
||||||
|
src/main/java/forge/view/toolbox/CardViewer.java -text
|
||||||
|
src/main/java/forge/view/toolbox/FOverlay.java -text
|
||||||
|
src/main/java/forge/view/toolbox/FVerticalTabPanel.java -text
|
||||||
src/main/java/net/slightlymagic/braids/LICENSE.txt svneol=native#text/plain
|
src/main/java/net/slightlymagic/braids/LICENSE.txt svneol=native#text/plain
|
||||||
src/main/java/net/slightlymagic/braids/util/ClumsyRunnable.java svneol=native#text/plain
|
src/main/java/net/slightlymagic/braids/util/ClumsyRunnable.java svneol=native#text/plain
|
||||||
src/main/java/net/slightlymagic/braids/util/ImmutableIterableFrom.java svneol=native#text/plain
|
src/main/java/net/slightlymagic/braids/util/ImmutableIterableFrom.java svneol=native#text/plain
|
||||||
|
|||||||
14
.gitignore
vendored
@@ -17,8 +17,22 @@ res/quest/questData.dat
|
|||||||
res/quest/questData.dat.xml
|
res/quest/questData.dat.xml
|
||||||
res/reprintSetInfo.log
|
res/reprintSetInfo.log
|
||||||
res/setInfoScript.log
|
res/setInfoScript.log
|
||||||
|
src/main/java/forge/control
|
||||||
|
src/main/java/forge/gui/control
|
||||||
|
src/main/java/forge/gui/ds
|
||||||
|
src/main/java/forge/gui/editor
|
||||||
|
src/main/java/forge/gui/home
|
||||||
src/main/java/forge/gui/match
|
src/main/java/forge/gui/match
|
||||||
|
src/main/java/forge/gui/matchOLD
|
||||||
src/main/java/forge/gui/toolbox
|
src/main/java/forge/gui/toolbox
|
||||||
src/main/java/forge/gui/unfinished
|
src/main/java/forge/gui/unfinished
|
||||||
|
src/main/java/forge/interfaces
|
||||||
|
src/main/java/forge/view/components
|
||||||
|
src/main/java/forge/view/controllers
|
||||||
|
src/main/java/forge/view/editor
|
||||||
|
src/main/java/forge/view/home
|
||||||
|
src/main/java/forge/view/interfaces
|
||||||
|
src/main/java/forge/view/match
|
||||||
|
src/main/java/forge/view/toolbox
|
||||||
/target
|
/target
|
||||||
/test-output
|
/test-output
|
||||||
|
|||||||
BIN
res/images/skins/default/bg_match.jpg
Normal file
|
After Width: | Height: | Size: 172 KiB |
BIN
res/images/skins/default/sprite.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 85 KiB |
BIN
res/images/skins/rebel/bg_match.jpg
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
res/images/skins/rebel/sprite.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 66 KiB |
BIN
res/images/symbols-13/detail_exile.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
res/images/symbols-13/detail_flashback.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
res/images/symbols-13/detail_grave.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
res/images/symbols-13/detail_hand.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
res/images/symbols-13/detail_library.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
res/images/symbols-13/detail_poison.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
@@ -134,7 +134,7 @@ NewGame/booster_text=Booster Draft (Schwierig) - W
|
|||||||
NewGame/yourdeck=Dein Deck
|
NewGame/yourdeck=Dein Deck
|
||||||
NewGame/opponent=Gegner
|
NewGame/opponent=Gegner
|
||||||
NewGame/deckeditor=Deck Editor
|
NewGame/deckeditor=Deck Editor
|
||||||
NewGame/newgui=New Gui
|
NewGame/oldgui=Old Gui
|
||||||
NewGame/ailand=Stack AI Land
|
NewGame/ailand=Stack AI Land
|
||||||
NewGame/devmode=Developer Mode
|
NewGame/devmode=Developer Mode
|
||||||
NewGame/questmode=Quest Mode
|
NewGame/questmode=Quest Mode
|
||||||
@@ -142,7 +142,7 @@ NewGame/startgame=Spiel starten
|
|||||||
NewGame/savesealed_msg=Please name this sealed deck
|
NewGame/savesealed_msg=Please name this sealed deck
|
||||||
NewGame/savesealed_ttl=Save Sealed Deck
|
NewGame/savesealed_ttl=Save Sealed Deck
|
||||||
|
|
||||||
WinLose/won=Siege:
|
WinLose/won=Siege:
|
||||||
WinLose/lost=, Niederlagen:
|
WinLose/lost=, Niederlagen:
|
||||||
WinLose/win=Gewonnen
|
WinLose/win=Gewonnen
|
||||||
WinLose/lose=Verloren
|
WinLose/lose=Verloren
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ NewGame/booster_text=Booster Draft (Hard) - Pick cards 1 at a time to create you
|
|||||||
NewGame/yourdeck=Your Deck
|
NewGame/yourdeck=Your Deck
|
||||||
NewGame/opponent=Opponent
|
NewGame/opponent=Opponent
|
||||||
NewGame/deckeditor=Deck Editor
|
NewGame/deckeditor=Deck Editor
|
||||||
NewGame/newgui=New Gui
|
NewGame/oldgui=Old Gui
|
||||||
NewGame/ailand=Stack AI Land
|
NewGame/ailand=Stack AI Land
|
||||||
NewGame/devmode=Developer Mode
|
NewGame/devmode=Developer Mode
|
||||||
NewGame/questmode=Quest Mode
|
NewGame/questmode=Quest Mode
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import forge.card.trigger.TriggerHandler;
|
|||||||
import forge.deck.DeckManager;
|
import forge.deck.DeckManager;
|
||||||
import forge.game.GameSummary;
|
import forge.game.GameSummary;
|
||||||
import forge.gui.input.InputControl;
|
import forge.gui.input.InputControl;
|
||||||
|
import forge.view.toolbox.FOverlay;
|
||||||
import forge.gui.skin.FSkin;
|
import forge.gui.skin.FSkin;
|
||||||
import forge.model.FGameState;
|
import forge.model.FGameState;
|
||||||
import forge.properties.ForgeProps;
|
import forge.properties.ForgeProps;
|
||||||
@@ -78,6 +79,9 @@ public final class AllZone {
|
|||||||
/** Global <code>display</code>. */
|
/** Global <code>display</code>. */
|
||||||
private static Display display;
|
private static Display display;
|
||||||
|
|
||||||
|
/** Global <code>overlay</code>. */
|
||||||
|
private static FOverlay overlay;
|
||||||
|
|
||||||
/** Constant <code>DECK_MGR</code>. */
|
/** Constant <code>DECK_MGR</code>. */
|
||||||
private static DeckManager deckManager;
|
private static DeckManager deckManager;
|
||||||
|
|
||||||
@@ -629,4 +633,18 @@ public final class AllZone {
|
|||||||
public static void setSkin(final FSkin fs) {
|
public static void setSkin(final FSkin fs) {
|
||||||
skin = fs;
|
skin = fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return overlay
|
||||||
|
*/
|
||||||
|
public static FOverlay getOverlay() {
|
||||||
|
return overlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param overlay0   Overlay panel
|
||||||
|
*/
|
||||||
|
public static void setOverlay(FOverlay overlay0) {
|
||||||
|
overlay = overlay0;
|
||||||
|
}
|
||||||
} // AllZone
|
} // AllZone
|
||||||
|
|||||||
@@ -40,10 +40,17 @@ public final class Constant {
|
|||||||
public static final boolean[] MILL = new boolean[1];
|
public static final boolean[] MILL = new boolean[1];
|
||||||
|
|
||||||
/** The Constant DevMode. */
|
/** The Constant DevMode. */
|
||||||
public static final boolean[] DEV_MODE = new boolean[1]; // one for
|
// one for normal mode, one for quest mode
|
||||||
// normal mode
|
public static final boolean[] DEV_MODE = new boolean[1];
|
||||||
// one for quest
|
|
||||||
// mode
|
/** The Constant HANDVIEW. */
|
||||||
|
public static final boolean[] HANDVIEW = new boolean[1];
|
||||||
|
|
||||||
|
/** The Constant LIBRARYVIEW. */
|
||||||
|
public static final boolean[] LIBRARYVIEW = new boolean[1];
|
||||||
|
|
||||||
|
/** The Constant OLDGUI. */
|
||||||
|
public static final boolean[] OLDGUI = new boolean[1];
|
||||||
|
|
||||||
/** The Constant NetConn. */
|
/** The Constant NetConn. */
|
||||||
public static final boolean[] NET_CONN = new boolean[1];
|
public static final boolean[] NET_CONN = new boolean[1];
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import forge.properties.ForgeProps;
|
|||||||
import forge.properties.NewConstants.Lang.GameAction.GameActionText;
|
import forge.properties.NewConstants.Lang.GameAction.GameActionText;
|
||||||
import forge.quest.gui.QuestWinLoseHandler;
|
import forge.quest.gui.QuestWinLoseHandler;
|
||||||
import forge.quest.gui.main.QuestEvent;
|
import forge.quest.gui.main.QuestEvent;
|
||||||
|
import forge.view.match.ViewTopLevel;
|
||||||
import forge.view.swing.WinLoseFrame;
|
import forge.view.swing.WinLoseFrame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -776,14 +777,22 @@ public class GameAction {
|
|||||||
final boolean refreeze = AllZone.getStack().isFrozen();
|
final boolean refreeze = AllZone.getStack().isFrozen();
|
||||||
AllZone.getStack().setFrozen(true);
|
AllZone.getStack().setFrozen(true);
|
||||||
|
|
||||||
final JFrame frame = (JFrame) AllZone.getDisplay();
|
if (Constant.Runtime.OLDGUI[0]) {
|
||||||
if (!frame.isDisplayable()) {
|
final JFrame frame = (JFrame) AllZone.getDisplay();
|
||||||
return;
|
if (!frame.isDisplayable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final ViewTopLevel frame = (ViewTopLevel) AllZone.getDisplay();
|
||||||
|
if (!frame.isDisplayable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.canShowWinLose && this.checkEndGameSate()) {
|
if (this.canShowWinLose && this.checkEndGameSate()) {
|
||||||
AllZone.getDisplay().savePrefs();
|
AllZone.getDisplay().savePrefs();
|
||||||
frame.setEnabled(false);
|
//frame.setEnabled(false);
|
||||||
// frame.dispose();
|
// frame.dispose();
|
||||||
|
|
||||||
// Gui_WinLose gwl = new Gui_WinLose(AllZone.getMatchState(),
|
// Gui_WinLose gwl = new Gui_WinLose(AllZone.getMatchState(),
|
||||||
|
|||||||
@@ -516,6 +516,9 @@ public class Phase extends MyObservable implements java.io.Serializable {
|
|||||||
this.turn++;
|
this.turn++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Visual indicators
|
||||||
|
PhaseUtil.visuallyActivatePhase(this.getPhase());
|
||||||
|
|
||||||
// When consecutively skipping phases (like in combat) this section
|
// When consecutively skipping phases (like in combat) this section
|
||||||
// pushes through that block
|
// pushes through that block
|
||||||
this.updateObservers();
|
this.updateObservers();
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import java.util.HashMap;
|
|||||||
import forge.Constant.Zone;
|
import forge.Constant.Zone;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.gui.input.Input;
|
import forge.gui.input.Input;
|
||||||
|
import forge.view.match.ViewField.PhaseLabel;
|
||||||
|
import forge.view.match.ViewTopLevel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -423,6 +425,7 @@ public class PhaseUtil {
|
|||||||
*/
|
*/
|
||||||
public static void handleUpkeep() {
|
public static void handleUpkeep() {
|
||||||
Player turn = AllZone.getPhase().getPlayerTurn();
|
Player turn = AllZone.getPhase().getPlayerTurn();
|
||||||
|
|
||||||
if (skipUpkeep()) {
|
if (skipUpkeep()) {
|
||||||
// Slowtrips all say "on the next turn's upkeep" if there is no
|
// Slowtrips all say "on the next turn's upkeep" if there is no
|
||||||
// upkeep next turn, the trigger will never occur.
|
// upkeep next turn, the trigger will never occur.
|
||||||
@@ -623,4 +626,46 @@ public class PhaseUtil {
|
|||||||
|| phase.equals(Constant.Phase.DRAW) || phase.equals(Constant.Phase.MAIN1)
|
|| phase.equals(Constant.Phase.DRAW) || phase.equals(Constant.Phase.MAIN1)
|
||||||
|| phase.equals(Constant.Phase.COMBAT_BEGIN);
|
|| phase.equals(Constant.Phase.COMBAT_BEGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves and visually activates phase label for appropriate
|
||||||
|
* phase and player.
|
||||||
|
*
|
||||||
|
* @param s   Phase state
|
||||||
|
*/
|
||||||
|
public static void visuallyActivatePhase(String s) {
|
||||||
|
PhaseLabel lbl = null;
|
||||||
|
Player p = AllZone.getPhase().getPlayerTurn();
|
||||||
|
ViewTopLevel t = (ViewTopLevel) AllZone.getDisplay();
|
||||||
|
|
||||||
|
int i; // Index of field; computer is 0, human is 1
|
||||||
|
if (p.isComputer()) {
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.equals(Constant.Phase.UPKEEP)) {
|
||||||
|
lbl = t.getFieldControllers().get(i).getView().getLblUpkeep();
|
||||||
|
}
|
||||||
|
else if (s.equals(Constant.Phase.DRAW)) {
|
||||||
|
lbl = t.getFieldControllers().get(i).getView().getLblDraw();
|
||||||
|
}
|
||||||
|
else if (s.equals(Constant.Phase.COMBAT_BEGIN)) {
|
||||||
|
lbl = t.getFieldControllers().get(i).getView().getLblBeginCombat();
|
||||||
|
}
|
||||||
|
else if (s.equals(Constant.Phase.COMBAT_END)) {
|
||||||
|
lbl = t.getFieldControllers().get(i).getView().getLblEndCombat();
|
||||||
|
}
|
||||||
|
else if (s.equals(Constant.Phase.END_OF_TURN)) {
|
||||||
|
lbl = t.getFieldControllers().get(i).getView().getLblEndTurn();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
t.getController().resetAllPhaseButtons();
|
||||||
|
lbl.setActive(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
98
src/main/java/forge/control/ControlAllUI.java
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
package forge.control;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
|
||||||
|
import javax.swing.JLayeredPane;
|
||||||
|
|
||||||
|
import forge.view.GuiTopLevel;
|
||||||
|
import forge.view.editor.EditorTopLevel;
|
||||||
|
import forge.view.home.HomeTopLevel;
|
||||||
|
import forge.view.match.ViewTopLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>ControlAllUI.</p>
|
||||||
|
* Controls all Forge UI functionality inside one JFrame.
|
||||||
|
* This class switches between various display states in that JFrame.
|
||||||
|
* Controllers are instantiated separately by each state's top level view class.
|
||||||
|
*/
|
||||||
|
public class ControlAllUI {
|
||||||
|
private JLayeredPane display;
|
||||||
|
private GuiTopLevel view;
|
||||||
|
private HomeTopLevel home = null;
|
||||||
|
private ViewTopLevel match = null;
|
||||||
|
private EditorTopLevel editor = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>ControlAllUI.</p>
|
||||||
|
* Controls all Forge UI functionality inside one JFrame.
|
||||||
|
* This class switches between various display states in that JFrame.
|
||||||
|
* Controllers are instantiated separately by each state's top level view class.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ControlAllUI() {
|
||||||
|
view = new GuiTopLevel();
|
||||||
|
|
||||||
|
view.addComponentListener(new ComponentAdapter() {
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
Component[] children;
|
||||||
|
children = display.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER);
|
||||||
|
children[0].setSize(display.getSize());
|
||||||
|
|
||||||
|
children = display.getComponentsInLayer(JLayeredPane.MODAL_LAYER);
|
||||||
|
children[0].setSize(display.getSize());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
display = (JLayeredPane) view.getContentPane();
|
||||||
|
|
||||||
|
changeState(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>changeState.</p>
|
||||||
|
* Switches between display states in top level JFrame.
|
||||||
|
*
|
||||||
|
* @param i   State index: 0 for home, 1 for match, etc.
|
||||||
|
*/
|
||||||
|
public void changeState(int i) {
|
||||||
|
home = null;
|
||||||
|
match = null;
|
||||||
|
editor = null;
|
||||||
|
|
||||||
|
display.removeAll();
|
||||||
|
view.addOverlay();
|
||||||
|
|
||||||
|
// Fire up new state
|
||||||
|
switch (i) {
|
||||||
|
case 0: // Home screen
|
||||||
|
home = new HomeTopLevel();
|
||||||
|
display.add(home);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // Match screen
|
||||||
|
match = new ViewTopLevel();
|
||||||
|
display.add(match, JLayeredPane.DEFAULT_LAYER);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // Deck editor screen
|
||||||
|
editor = new EditorTopLevel();
|
||||||
|
display.add(editor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ViewTopLevel */
|
||||||
|
public ViewTopLevel getMatchView() {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlMatchUI */
|
||||||
|
public ControlMatchUI getMatchController() {
|
||||||
|
return match.getController();
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/main/java/forge/control/ControlEditorUI.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package forge.control;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>ControlEditorUI</p>
|
||||||
|
* Top-level controller for deck editor.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ControlEditorUI extends JPanel {
|
||||||
|
/**
|
||||||
|
* <p>ControlEditorUI</p>
|
||||||
|
* Top-level controller for deck editor.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ControlEditorUI() {
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/main/java/forge/control/ControlHomeUI.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package forge.control;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this type.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ControlHomeUI {
|
||||||
|
|
||||||
|
}
|
||||||
240
src/main/java/forge/control/ControlMatchUI.java
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
package forge.control;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.InputMap;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Singletons;
|
||||||
|
import forge.Constant.Zone;
|
||||||
|
import forge.control.match.ControlField;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import forge.properties.ForgePreferences;
|
||||||
|
import forge.view.match.ViewTopLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>ControlMatchUI</p>
|
||||||
|
* Top-level controller for matches. Implements Display.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ControlMatchUI {
|
||||||
|
private ViewTopLevel view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>ControlMatchUI</p>
|
||||||
|
* Constructs instance of match UI controller, used as a single
|
||||||
|
* point of top-level control for child UIs - in other words, this class
|
||||||
|
* controls the controllers. Tasks targeting the view of individual
|
||||||
|
* components are found in a separate controller for that component
|
||||||
|
* and should not be included here.
|
||||||
|
*
|
||||||
|
* This constructor is called after child components have been instantiated.
|
||||||
|
* When children are instantiated, they also instantiate their controller.
|
||||||
|
* So, this class must be called after everything is already in place.
|
||||||
|
*
|
||||||
|
* @param v   A ViewTopLevel object
|
||||||
|
*/
|
||||||
|
public ControlMatchUI(ViewTopLevel v) {
|
||||||
|
view = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires up controllers for each component of UI.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void initMatch() {
|
||||||
|
// All child components have been assembled; observers and listeners can
|
||||||
|
// be added safely.
|
||||||
|
view.getAreaSidebar().getTabber().getController().addObservers();
|
||||||
|
view.getAreaSidebar().getTabber().getController().addListeners();
|
||||||
|
|
||||||
|
view.getAreaUser().getPnlInput().getController().addListeners();
|
||||||
|
|
||||||
|
view.getAreaUser().getPnlHand().getController().addObservers();
|
||||||
|
view.getAreaUser().getPnlHand().getController().addListeners();
|
||||||
|
|
||||||
|
// Update all observers with values for start of match.
|
||||||
|
List<ControlField> fieldControllers = view.getFieldControllers();
|
||||||
|
for (ControlField f : fieldControllers) {
|
||||||
|
f.addObservers();
|
||||||
|
f.addListeners();
|
||||||
|
f.getPlayer().updateObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
AllZone.getHumanPlayer().getZone(Zone.Hand).updateObservers();
|
||||||
|
AllZone.getComputerPlayer().getZone(Zone.Hand).updateObservers();
|
||||||
|
AllZone.getStack().updateObservers();
|
||||||
|
AllZone.getHumanPlayer().getZone(Zone.Battlefield).updateObservers();
|
||||||
|
AllZone.getInputControl().updateObservers();
|
||||||
|
view.getAreaSidebar().getTabber().getController().updateObservers();
|
||||||
|
this.mapKeyboardShortcuts();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets all phase buttons in all fields to "inactive", so highlight won't be
|
||||||
|
* drawn on them. "Enabled" state remains the same.
|
||||||
|
*/
|
||||||
|
// This method is in the top-level controller because it affects ALL fields (not just one).
|
||||||
|
public void resetAllPhaseButtons() {
|
||||||
|
List<ControlField> fieldControllers = view.getFieldControllers();
|
||||||
|
|
||||||
|
for (ControlField c : fieldControllers) {
|
||||||
|
c.resetPhaseButtons();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps actions to shortcuts, and attaches each shortcut to the
|
||||||
|
* InputMap of the top level view.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
private void mapKeyboardShortcuts() {
|
||||||
|
InputMap im = ((ViewTopLevel) AllZone.getDisplay()).getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||||
|
ForgePreferences fp = Singletons.getModel().getPreferences();
|
||||||
|
String str;
|
||||||
|
KeyStroke key;
|
||||||
|
|
||||||
|
// Actions which correspond to key presses
|
||||||
|
Action actShowStack = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) { view.getTabberController().showPnlStack(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
Action actShowCombat = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) { view.getTabberController().showPnlCombat(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
Action actShowConsole = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) { view.getTabberController().showPnlConsole(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
Action actShowPlayers = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) { view.getTabberController().showPnlPlayers(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
Action actShowDev = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) { view.getTabberController().showPnlDev(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
Action actConcede = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) { view.getDockController().concede(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
Action actShowPicture = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) { view.getCardviewerController().showPnlCardPic(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
Action actShowDetail = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) { view.getCardviewerController().showPnlCardDetail(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Show stack
|
||||||
|
// (Get keycode string, convert to char, convert to keystroke, put on input map.)
|
||||||
|
str = fp.getShowStackShortcut();
|
||||||
|
key = KeyStroke.getKeyStroke(codes2Chars(str));
|
||||||
|
|
||||||
|
im.put(key, str);
|
||||||
|
((ViewTopLevel) AllZone.getDisplay()).getActionMap().put(im.get(key), actShowStack);
|
||||||
|
|
||||||
|
// Show combat
|
||||||
|
str = fp.getShowCombatShortcut();
|
||||||
|
key = KeyStroke.getKeyStroke(codes2Chars(str));
|
||||||
|
|
||||||
|
im.put(key, str);
|
||||||
|
((ViewTopLevel) AllZone.getDisplay()).getActionMap().put(im.get(key), actShowCombat);
|
||||||
|
|
||||||
|
// Show console
|
||||||
|
str = fp.getShowConsoleShortcut();
|
||||||
|
key = KeyStroke.getKeyStroke(codes2Chars(str));
|
||||||
|
|
||||||
|
im.put(key, str);
|
||||||
|
((ViewTopLevel) AllZone.getDisplay()).getActionMap().put(im.get(key), actShowConsole);
|
||||||
|
|
||||||
|
// Show players
|
||||||
|
str = fp.getShowPlayersShortcut();
|
||||||
|
key = KeyStroke.getKeyStroke(codes2Chars(str));
|
||||||
|
|
||||||
|
im.put(key, str);
|
||||||
|
((ViewTopLevel) AllZone.getDisplay()).getActionMap().put(im.get(key), actShowPlayers);
|
||||||
|
|
||||||
|
// Show devmode
|
||||||
|
str = fp.getShowDevShortcut();
|
||||||
|
key = KeyStroke.getKeyStroke(codes2Chars(str));
|
||||||
|
|
||||||
|
im.put(key, str);
|
||||||
|
((ViewTopLevel) AllZone.getDisplay()).getActionMap().put(im.get(key), actShowDev);
|
||||||
|
|
||||||
|
// Concede game
|
||||||
|
str = fp.getConcedeShortcut();
|
||||||
|
key = KeyStroke.getKeyStroke(codes2Chars(str));
|
||||||
|
|
||||||
|
im.put(key, str);
|
||||||
|
((ViewTopLevel) AllZone.getDisplay()).getActionMap().put(im.get(key), actConcede);
|
||||||
|
|
||||||
|
// Show card picture
|
||||||
|
str = fp.getShowPictureShortcut();
|
||||||
|
key = KeyStroke.getKeyStroke(codes2Chars(str));
|
||||||
|
|
||||||
|
im.put(key, str);
|
||||||
|
((ViewTopLevel) AllZone.getDisplay()).getActionMap().put(im.get(key), actShowPicture);
|
||||||
|
|
||||||
|
// Show card detail
|
||||||
|
str = fp.getShowDetailShortcut();
|
||||||
|
key = KeyStroke.getKeyStroke(codes2Chars(str));
|
||||||
|
|
||||||
|
im.put(key, str);
|
||||||
|
((ViewTopLevel) AllZone.getDisplay()).getActionMap().put(im.get(key), actShowDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string of key codes (space delimited) into their respective
|
||||||
|
* key texts. This helps juggling between input maps, display text, save
|
||||||
|
* values, and input data.
|
||||||
|
*
|
||||||
|
* @param s0   A string of keycodes
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
private String codes2Chars(String s0) {
|
||||||
|
List<String> codes = new ArrayList<String>(Arrays.asList(s0.split(" ")));
|
||||||
|
List<String> displayText = new ArrayList<String>();
|
||||||
|
String temp;
|
||||||
|
|
||||||
|
for (String s : codes) {
|
||||||
|
temp = KeyEvent.getKeyText(Integer.valueOf(s));
|
||||||
|
|
||||||
|
if (!s.isEmpty()) {
|
||||||
|
// Probably a better way to do this; but I couldn't find it
|
||||||
|
// after a decent look around. The main problem is that
|
||||||
|
// KeyEvent.getKeyText() will return "Ctrl", but the input
|
||||||
|
// map expects "control". Similar case problems with Shift and Alt.
|
||||||
|
// Doublestrike 21-11-11
|
||||||
|
if (temp.equalsIgnoreCase("ctrl")) {
|
||||||
|
temp = "control";
|
||||||
|
}
|
||||||
|
else if (temp.equalsIgnoreCase("shift")) {
|
||||||
|
temp = "shift";
|
||||||
|
}
|
||||||
|
else if (temp.equalsIgnoreCase("alt")) {
|
||||||
|
temp = "alt";
|
||||||
|
}
|
||||||
|
else if (temp.equalsIgnoreCase("escape")) {
|
||||||
|
temp = "escape";
|
||||||
|
}
|
||||||
|
|
||||||
|
displayText.add(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringUtils.join(displayText, ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
64
src/main/java/forge/control/match/ControlCardviewer.java
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package forge.control.match;
|
||||||
|
|
||||||
|
import java.awt.Image;
|
||||||
|
|
||||||
|
import forge.Card;
|
||||||
|
import forge.ImageCache;
|
||||||
|
import forge.view.match.ViewCardviewer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Controls the vertical tabber in sidebar used for
|
||||||
|
* viewing card details and picture.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ControlCardviewer {
|
||||||
|
private ViewCardviewer view;
|
||||||
|
private Card currentCard = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the vertical tabber in sidebar used for
|
||||||
|
* viewing card details and picture.
|
||||||
|
* @param v   The CardViewer Swing component.
|
||||||
|
*/
|
||||||
|
public ControlCardviewer(ViewCardviewer v) {
|
||||||
|
view = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows card details and/or picture in sidebar cardview tabber.
|
||||||
|
* @param c   Card object
|
||||||
|
*/
|
||||||
|
public void showCard(Card c) {
|
||||||
|
Image img = ImageCache.getImage(c);
|
||||||
|
this.currentCard = c;
|
||||||
|
view.getPnlCardPic().setCard(c);
|
||||||
|
view.getPnlCardDetail().setCard(c);
|
||||||
|
|
||||||
|
if (img != null) {
|
||||||
|
showPnlCardPic();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
showPnlCardDetail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return Card */
|
||||||
|
public Card getCurrentCard() {
|
||||||
|
return currentCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Programatically forces card layout of sidebar tabber to show "CardDetail" panel.
|
||||||
|
*/
|
||||||
|
public void showPnlCardDetail() {
|
||||||
|
view.getVtpCardviewer().showTab(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Programatically forces card layout of sidebar tabber to show card picture panel.
|
||||||
|
*/
|
||||||
|
public void showPnlCardPic() {
|
||||||
|
view.getVtpCardviewer().showTab(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
106
src/main/java/forge/control/match/ControlDock.java
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package forge.control.match;
|
||||||
|
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Singletons;
|
||||||
|
import forge.properties.ForgePreferences;
|
||||||
|
import forge.view.match.ViewDock;
|
||||||
|
import forge.view.match.ViewDock.KeyboardShortcutField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child controller, handles dock button operations.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ControlDock {
|
||||||
|
private ViewDock view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child controller, handles dock button operations.
|
||||||
|
* @param v   ViewDock obj
|
||||||
|
*/
|
||||||
|
public ControlDock(ViewDock v) {
|
||||||
|
view = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Concede game, bring up WinLose UI. */
|
||||||
|
public void concede() {
|
||||||
|
AllZone.getHumanPlayer().concede();
|
||||||
|
AllZone.getGameAction().checkStateEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ViewDock */
|
||||||
|
public ViewDock getView() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Updates and saves ForgePreferences with current shortcuts. */
|
||||||
|
public void saveKeyboardShortcuts() {
|
||||||
|
ForgePreferences fp = Singletons.getModel().getPreferences();
|
||||||
|
Map<String, KeyboardShortcutField> shortcuts = view.getKeyboardShortcutFields();
|
||||||
|
|
||||||
|
fp.setShowStackShortcut(shortcuts.get("showstack").getCodeString());
|
||||||
|
fp.setShowCombatShortcut(shortcuts.get("showcombat").getCodeString());
|
||||||
|
fp.setShowPlayersShortcut(shortcuts.get("showplayers").getCodeString());
|
||||||
|
fp.setShowConsoleShortcut(shortcuts.get("showconsole").getCodeString());
|
||||||
|
fp.setShowDevShortcut(shortcuts.get("showdev").getCodeString());
|
||||||
|
fp.setConcedeShortcut(shortcuts.get("concede").getCodeString());
|
||||||
|
fp.setShowPictureShortcut(shortcuts.get("showpicture").getCodeString());
|
||||||
|
fp.setShowDetailShortcut(shortcuts.get("showdetail").getCodeString());
|
||||||
|
|
||||||
|
try {
|
||||||
|
fp.save();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
AllZone.getOverlay().hideOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* - Adds keycode to list stored in name of a text field.
|
||||||
|
* - Code is not added if already in list.
|
||||||
|
* - Backspace removes last code in list.
|
||||||
|
* - Sets text of text field with character equivalent of keycodes.
|
||||||
|
*
|
||||||
|
* @param e   KeyEvent
|
||||||
|
*/
|
||||||
|
public void addKeyCode(KeyEvent e) {
|
||||||
|
KeyboardShortcutField ksf = (KeyboardShortcutField) e.getSource();
|
||||||
|
String newCode = Integer.toString(e.getKeyCode());
|
||||||
|
String codestring = ksf.getCodeString();
|
||||||
|
List<String> existingCodes;
|
||||||
|
|
||||||
|
if (codestring != null) {
|
||||||
|
existingCodes = new ArrayList<String>(Arrays.asList(codestring.split(" ")));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
existingCodes = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backspace (8) will remove last code from list.
|
||||||
|
if (e.getKeyCode() == 8) {
|
||||||
|
existingCodes.remove(existingCodes.size() - 1);
|
||||||
|
}
|
||||||
|
else if (!existingCodes.contains(newCode)) {
|
||||||
|
existingCodes.add(newCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
ksf.setCodeString(StringUtils.join(existingCodes, ' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
public void endTurn() {
|
||||||
|
// Big thanks to you, Gameplay Guru, since I was too lazy to figure this out
|
||||||
|
// before release. Doublestrike 24-11-11
|
||||||
|
System.err.println("forge.control.match > ControlDock > endTurn()");
|
||||||
|
System.out.println("Should skip to the end of turn, or entire turn.");
|
||||||
|
System.err.println("If some gameplay guru could implement this, that would be great...");
|
||||||
|
}
|
||||||
|
}
|
||||||
459
src/main/java/forge/control/match/ControlField.java
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
package forge.control.match;
|
||||||
|
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.datatransfer.StringSelection;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseMotionAdapter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
import net.slightlymagic.braids.util.ImmutableIterableFrom;
|
||||||
|
|
||||||
|
import com.google.code.jyield.Generator;
|
||||||
|
import com.google.code.jyield.YieldUtils;
|
||||||
|
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Card;
|
||||||
|
import forge.CardList;
|
||||||
|
import forge.Constant;
|
||||||
|
import forge.Constant.Zone;
|
||||||
|
import forge.GuiDisplayUtil;
|
||||||
|
import forge.Player;
|
||||||
|
import forge.PlayerZone;
|
||||||
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
|
import forge.deck.Deck;
|
||||||
|
import forge.gui.ForgeAction;
|
||||||
|
import forge.gui.GuiUtils;
|
||||||
|
import forge.gui.input.Input;
|
||||||
|
import forge.gui.input.InputAttack;
|
||||||
|
import forge.gui.input.InputBlock;
|
||||||
|
import forge.gui.input.InputPayManaCost;
|
||||||
|
import forge.gui.input.InputPayManaCostAbility;
|
||||||
|
import forge.item.CardPrinted;
|
||||||
|
import forge.properties.ForgeProps;
|
||||||
|
import forge.properties.NewConstants;
|
||||||
|
import forge.properties.NewConstants.Lang.GuiDisplay.ComputerHand;
|
||||||
|
import forge.properties.NewConstants.Lang.GuiDisplay.ComputerLibrary;
|
||||||
|
import forge.view.match.ViewField;
|
||||||
|
import forge.view.match.ViewTopLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child controller, applied to single field in battlefield.
|
||||||
|
* Manages player view functions such as card observers,
|
||||||
|
* life total changes, graveyard button click, etc.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ControlField {
|
||||||
|
private Player player;
|
||||||
|
private ViewField view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child controller, applied to single field in battlefield.
|
||||||
|
* Manages player view functions such as card observers,
|
||||||
|
* life total changes, graveyard button click, etc.
|
||||||
|
*
|
||||||
|
* @param p   The Player this field applies to
|
||||||
|
* @param v   The Swing component for this field
|
||||||
|
*/
|
||||||
|
public ControlField(Player p, ViewField v) {
|
||||||
|
player = p;
|
||||||
|
view = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return Player */
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ViewField */
|
||||||
|
public ViewField getView() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds observers to field components where required: card stats, player stats, etc.
|
||||||
|
*/
|
||||||
|
public void addObservers() {
|
||||||
|
// Hand, Graveyard, Library, Flashback, Exile totals, attached to respective Zones.
|
||||||
|
Observer o1 = new Observer() {
|
||||||
|
@Override
|
||||||
|
public void update(final Observable a, final Object b) {
|
||||||
|
view.updateZones(player);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
player.getZone(Zone.Hand).addObserver(o1);
|
||||||
|
|
||||||
|
// Life total, poison total, and keywords, attached directly to Player.
|
||||||
|
Observer o2 = new Observer() {
|
||||||
|
@Override
|
||||||
|
public void update(final Observable a, final Object b) {
|
||||||
|
view.updateDetails(player);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
player.addObserver(o2);
|
||||||
|
|
||||||
|
// Card play area, attached to battlefield zone.
|
||||||
|
Observer o3 = new Observer() {
|
||||||
|
public void update(final Observable a, final Object b) {
|
||||||
|
PlayerZone pZone = (PlayerZone) a;
|
||||||
|
Card[] c = pZone.getCards(false);
|
||||||
|
GuiDisplayUtil.setupPlayZone(view.getTabletop(), c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
player.getZone(Zone.Battlefield).addObserver(o3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listeners for user actions on the battlefield.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void addListeners() {
|
||||||
|
// When/if zone action properties become less specific, the conditional
|
||||||
|
// tests for computer/human players can be removed. If that's not ever
|
||||||
|
// going to happen, this comment can be removed. :) Doublestrike 29-10-11.
|
||||||
|
|
||||||
|
this.addZoneListeners();
|
||||||
|
|
||||||
|
// Battlefield card clicks
|
||||||
|
view.getTabletop().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(final MouseEvent e) {
|
||||||
|
ViewTopLevel t = (ViewTopLevel) AllZone.getDisplay();
|
||||||
|
Card c = t.getCardviewerController().getCurrentCard();
|
||||||
|
Input input = t.getInputController().getInputControl().getInput();
|
||||||
|
|
||||||
|
if (c != null) {
|
||||||
|
if (c.isTapped()
|
||||||
|
&& (input instanceof InputPayManaCost
|
||||||
|
|| input instanceof InputPayManaCostAbility)) {
|
||||||
|
arcane.ui.CardPanel cardPanel = view.getTabletop().getCardPanel(c.getUniqueNumber());
|
||||||
|
for (arcane.ui.CardPanel cp : cardPanel.getAttachedPanels()) {
|
||||||
|
if (cp.getCard().isUntapped()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CardList att = new CardList(AllZone.getCombat().getAttackers());
|
||||||
|
if ((c.isTapped() || c.hasSickness() || ((c.hasKeyword("Vigilance")) && att.contains(c)))
|
||||||
|
&& (input instanceof InputAttack)) {
|
||||||
|
arcane.ui.CardPanel cardPanel = view.getTabletop().getCardPanel(c.getUniqueNumber());
|
||||||
|
for (arcane.ui.CardPanel cp : cardPanel.getAttachedPanels()) {
|
||||||
|
if (cp.getCard().isUntapped() && !cp.getCard().hasSickness()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.isMetaDown()) {
|
||||||
|
if (att.contains(c) && (input instanceof InputAttack)
|
||||||
|
&& !c.hasKeyword("CARDNAME attacks each turn if able.")) {
|
||||||
|
c.untap();
|
||||||
|
AllZone.getCombat().removeFromCombat(c);
|
||||||
|
} else if (input instanceof InputBlock) {
|
||||||
|
if (c.getController().isHuman()) {
|
||||||
|
AllZone.getCombat().removeFromCombat(c);
|
||||||
|
}
|
||||||
|
((InputBlock) input).removeFromAllBlocking(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
t.getInputController().getInputControl().selectCard(c, AllZone.getHumanPlayer().getZone(Zone.Battlefield));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Battlefield card mouseover
|
||||||
|
view.getTabletop().addMouseMotionListener(new MouseMotionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(final MouseEvent me) {
|
||||||
|
ViewTopLevel t = (ViewTopLevel) AllZone.getDisplay();
|
||||||
|
Card c = view.getTabletop().getCardFromMouseOverPanel();
|
||||||
|
if (c != null) {
|
||||||
|
t.getCardviewerController().showCard(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Player select
|
||||||
|
view.getLblLife().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(final MouseEvent e) {
|
||||||
|
ViewTopLevel t = (ViewTopLevel) AllZone.getDisplay();
|
||||||
|
if (player.isComputer()) {
|
||||||
|
t.getInputController().getInputControl().selectPlayer(AllZone.getComputerPlayer());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
t.getInputController().getInputControl().selectPlayer(AllZone.getHumanPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} // End addListeners()
|
||||||
|
|
||||||
|
/** Adds listeners to "zone" labels: flashback, graveyard, etc.
|
||||||
|
* This method only exists to avoid the 150-line limit in the checkstyle rules.
|
||||||
|
*/
|
||||||
|
private void addZoneListeners() {
|
||||||
|
// Graveyard card list button
|
||||||
|
view.getLblGraveyard().enableHover();
|
||||||
|
view.getLblGraveyard().addMouseListener(new MouseAdapter() {
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if (player.isComputer()) {
|
||||||
|
new ZoneAction(player.getZone(Zone.Graveyard),
|
||||||
|
NewConstants.Lang.GuiDisplay.COMPUTER_GRAVEYARD).actionPerformed(null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
new ZoneAction(player.getZone(Zone.Graveyard),
|
||||||
|
NewConstants.Lang.GuiDisplay.HUMAN_GRAVEYARD).actionPerformed(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Exile card list button
|
||||||
|
view.getLblExile().enableHover();
|
||||||
|
view.getLblExile().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if (player.isComputer()) {
|
||||||
|
new ZoneAction(player.getZone(Zone.Exile),
|
||||||
|
NewConstants.Lang.GuiDisplay.COMPUTER_REMOVED).actionPerformed(null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
new ZoneAction(player.getZone(Zone.Exile),
|
||||||
|
NewConstants.Lang.GuiDisplay.HUMAN_REMOVED).actionPerformed(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Library card list button
|
||||||
|
view.getLblLibrary().enableHover();
|
||||||
|
view.getLblLibrary().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if (!player.isComputer()) {
|
||||||
|
new DeckListAction(NewConstants.Lang.GuiDisplay.HUMAN_DECKLIST).actionPerformed(null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// TODO DeckListAction has been rewritten to accept either human or computer
|
||||||
|
// decklists. However, NewConstants.Lang.GuiDisplay does not have a computer
|
||||||
|
// decklist available. That needs to be added for the below line to work
|
||||||
|
// properly. The current solution will work in the meantime. Doublestrike 15-11-11.
|
||||||
|
|
||||||
|
//new DeckListAction(NewConstants.Lang.GuiDisplay).actionPerformed(null);
|
||||||
|
|
||||||
|
new ZoneAction(player.getZone(Zone.Library), ComputerLibrary.BASE).actionPerformed(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Flashback card list button
|
||||||
|
view.getLblFlashback().enableHover();
|
||||||
|
view.getLblFlashback().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if (!player.isComputer()) {
|
||||||
|
new ZoneAction(player.getZone(Zone.Graveyard), NewConstants.Lang.GuiDisplay.HUMAN_FLASHBACK) {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 8120331222693706164L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Iterable<Card> getCardsAsIterable() {
|
||||||
|
return new ImmutableIterableFrom<Card>(CardFactoryUtil.getExternalZoneActivationCards(AllZone
|
||||||
|
.getHumanPlayer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doAction(final Card c) {
|
||||||
|
AllZone.getGameAction().playCard(c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Hand button
|
||||||
|
if (player.isComputer()) {
|
||||||
|
view.getLblHand().enableHover();
|
||||||
|
|
||||||
|
view.getLblHand().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
new ZoneAction(player.getZone(Zone.Hand), ComputerHand.BASE).actionPerformed(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets all phase buttons to "inactive", so highlight won't be
|
||||||
|
* drawn on them. "Enabled" state remains the same.
|
||||||
|
*/
|
||||||
|
public void resetPhaseButtons() {
|
||||||
|
view.getLblUpkeep().setActive(false);
|
||||||
|
view.getLblDraw().setActive(false);
|
||||||
|
view.getLblBeginCombat().setActive(false);
|
||||||
|
view.getLblEndCombat().setActive(false);
|
||||||
|
view.getLblEndTurn().setActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives click and programmatic requests for viewing data stacks
|
||||||
|
* in the "zones" of a player field: hand, library, etc.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class ZoneAction extends ForgeAction {
|
||||||
|
private static final long serialVersionUID = -5822976087772388839L;
|
||||||
|
private PlayerZone zone;
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives click and programmatic requests for viewing data stacks
|
||||||
|
* in the "zones" of a player field: hand, graveyard, etc. The library
|
||||||
|
* "zone" is an exception to the rule; it's handled in DeckListAction.
|
||||||
|
*
|
||||||
|
* @param zone   PlayerZone obj
|
||||||
|
* @param property   String obj
|
||||||
|
*/
|
||||||
|
public ZoneAction(final PlayerZone zone, final String property) {
|
||||||
|
super(property);
|
||||||
|
title = ForgeProps.getLocalized(property + "/title");
|
||||||
|
this.zone = zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param e   ActionEvent obj */
|
||||||
|
public void actionPerformed(final ActionEvent e) {
|
||||||
|
Generator<Card> c = YieldUtils.toGenerator(getCardsAsIterable());
|
||||||
|
|
||||||
|
if (AllZone.getNameChanger().shouldChangeCardName()) {
|
||||||
|
c = AllZone.getNameChanger().changeCard(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable<Card> myIterable = YieldUtils.toIterable(c);
|
||||||
|
ArrayList<Card> choices = YieldUtils.toArrayList(myIterable);
|
||||||
|
//System.out.println("immediately after: "+choices);
|
||||||
|
//Iterator<Card> iter = myIterable.iterator();
|
||||||
|
|
||||||
|
ArrayList<Card> choices2 = new ArrayList<Card>();
|
||||||
|
|
||||||
|
if (choices.isEmpty()) {
|
||||||
|
GuiUtils.getChoiceOptional(title, new String[]{"no cards"});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int i = 0; i < choices.size(); i++) {
|
||||||
|
Card crd = choices.get(i);
|
||||||
|
//System.out.println(crd+": "+crd.isFaceDown());
|
||||||
|
if (crd.isFaceDown()) {
|
||||||
|
Card faceDown = new Card();
|
||||||
|
faceDown.setName("Face Down");
|
||||||
|
choices2.add(faceDown);
|
||||||
|
//System.out.println("Added: "+faceDown);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
choices2.add(crd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//System.out.println("Face down cards replaced: "+choices2);
|
||||||
|
Card choice = (Card) GuiUtils.getChoiceOptional(title, choices2.toArray());
|
||||||
|
if (choice != null) {
|
||||||
|
doAction(choice);
|
||||||
|
/*
|
||||||
|
Card choice = GuiUtils.getChoiceOptional(title, iter);
|
||||||
|
if (choice != null) doAction(choice);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Iterable<Card> getCardsAsIterable() {
|
||||||
|
return new ImmutableIterableFrom<Card>(Arrays.asList(zone.getCards()));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doAction(final Card c) {
|
||||||
|
}
|
||||||
|
} // End ZoneAction
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives click and programmatic requests for viewing a player's
|
||||||
|
* library (typically used in dev mode). Allows copy of the
|
||||||
|
* cardlist to clipboard.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class DeckListAction extends ForgeAction {
|
||||||
|
public DeckListAction(final String property) {
|
||||||
|
super(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 9874492387239847L;
|
||||||
|
|
||||||
|
public void actionPerformed(final ActionEvent e) {
|
||||||
|
Deck targetDeck;
|
||||||
|
|
||||||
|
if (Constant.Runtime.HUMAN_DECK[0].countMain() > 1) {
|
||||||
|
targetDeck = Constant.Runtime.HUMAN_DECK[0];
|
||||||
|
}
|
||||||
|
else if (Constant.Runtime.COMPUTER_DECK[0].countMain() > 1) {
|
||||||
|
targetDeck = Constant.Runtime.COMPUTER_DECK[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<String, Integer> deckMap = new HashMap<String, Integer>();
|
||||||
|
|
||||||
|
for (Entry<CardPrinted, Integer> s : targetDeck.getMain()) {
|
||||||
|
deckMap.put(s.getKey().getName(), s.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
String nl = System.getProperty("line.separator");
|
||||||
|
StringBuilder deckList = new StringBuilder();
|
||||||
|
String dName = targetDeck.getName();
|
||||||
|
|
||||||
|
if (dName == null) {
|
||||||
|
dName = "";
|
||||||
|
} else {
|
||||||
|
deckList.append(dName + nl);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<String> dmKeys = new ArrayList<String>();
|
||||||
|
for (String s : deckMap.keySet()) {
|
||||||
|
dmKeys.add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(dmKeys);
|
||||||
|
|
||||||
|
for (String s : dmKeys) {
|
||||||
|
deckList.append(deckMap.get(s) + " x " + s + nl);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rcMsg = -1138;
|
||||||
|
String ttl = "Human's Decklist";
|
||||||
|
if (!dName.equals("")) {
|
||||||
|
ttl += " - " + dName;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
if (deckMap.keySet().size() <= 32) {
|
||||||
|
msg.append(deckList.toString() + nl);
|
||||||
|
} else {
|
||||||
|
msg.append("Decklist too long for dialog." + nl + nl);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.append("Copy Decklist to Clipboard?");
|
||||||
|
|
||||||
|
rcMsg = JOptionPane.showConfirmDialog(null, msg, ttl, JOptionPane.OK_CANCEL_OPTION);
|
||||||
|
|
||||||
|
if (rcMsg == JOptionPane.OK_OPTION) {
|
||||||
|
StringSelection ss = new StringSelection(deckList.toString());
|
||||||
|
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // End DeckListAction
|
||||||
|
}
|
||||||
128
src/main/java/forge/control/match/ControlHand.java
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
package forge.control.match;
|
||||||
|
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Card;
|
||||||
|
import forge.Constant.Zone;
|
||||||
|
import forge.PlayerZone;
|
||||||
|
import forge.view.match.ViewHand;
|
||||||
|
import forge.view.match.ViewHand.CardPanel;
|
||||||
|
import forge.view.match.ViewTopLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child controller - handles operations related to cards in user's hand
|
||||||
|
* and their Swing components, which are assembled in ViewHand.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ControlHand {
|
||||||
|
private List<Card> cardsInPanel;
|
||||||
|
private ViewHand view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child controller - handles operations related to cards in user's hand
|
||||||
|
* and their Swing components, which are assembled in ViewHand.
|
||||||
|
* @param v   The Swing component for user hand
|
||||||
|
*/
|
||||||
|
public ControlHand(ViewHand v) {
|
||||||
|
view = v;
|
||||||
|
cardsInPanel = new ArrayList<Card>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds observers to hand panel. */
|
||||||
|
public void addObservers() {
|
||||||
|
Observer o1 = new Observer() {
|
||||||
|
public void update(final Observable a, final Object b) {
|
||||||
|
resetCards(Arrays.asList(((PlayerZone) a).getCards()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
AllZone.getHumanPlayer().getZone(Zone.Hand).addObserver(o1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds listeners to hand panel: window resize, etc. */
|
||||||
|
public void addListeners() {
|
||||||
|
view.addComponentListener(new ComponentAdapter() {
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
// Ensures cards in hand scale properly with parent.
|
||||||
|
view.refreshLayout();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds various listeners for cards in hand. Uses CardPanel
|
||||||
|
* instance from ViewHand.
|
||||||
|
*
|
||||||
|
* @param c   CardPanel object
|
||||||
|
*/
|
||||||
|
public void addCardPanelListeners(final CardPanel c) {
|
||||||
|
// Grab top level controller to facilitate interaction between children
|
||||||
|
final ViewTopLevel display = (ViewTopLevel) (AllZone.getDisplay());
|
||||||
|
final Card cardobj = c.getCard();
|
||||||
|
|
||||||
|
// Sidebar pic/detail on card hover
|
||||||
|
c.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(final MouseEvent e) {
|
||||||
|
display.getCardviewerController().showCard(cardobj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Mouse press
|
||||||
|
c.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(final MouseEvent e) {
|
||||||
|
|
||||||
|
if (e.getButton() != MouseEvent.BUTTON1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
display.getInputController().getInputControl().selectCard(
|
||||||
|
cardobj, AllZone.getHumanPlayer().getZone(Zone.Hand));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param c   Card object */
|
||||||
|
public void addCard(Card c) {
|
||||||
|
cardsInPanel.add(c);
|
||||||
|
view.refreshLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param c   List of Card objects */
|
||||||
|
public void addCards(List<Card> c) {
|
||||||
|
cardsInPanel.addAll(c);
|
||||||
|
view.refreshLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return List<Card> */
|
||||||
|
public List<Card> getCards() {
|
||||||
|
return cardsInPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param c   Card object */
|
||||||
|
public void removeCard(Card c) {
|
||||||
|
cardsInPanel.remove(c);
|
||||||
|
view.refreshLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param c   List of Card objects */
|
||||||
|
public void removeCards(List<Card> c) {
|
||||||
|
cardsInPanel.removeAll(c);
|
||||||
|
view.refreshLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param c   List of Card objects */
|
||||||
|
public void resetCards(List<Card> c) {
|
||||||
|
cardsInPanel.clear();
|
||||||
|
addCards(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
88
src/main/java/forge/control/match/ControlInput.java
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package forge.control.match;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.KeyAdapter;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.GuiInput;
|
||||||
|
import forge.view.match.ViewInput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child controller - handles operations related to input panel.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ControlInput {
|
||||||
|
private ViewInput view;
|
||||||
|
|
||||||
|
private GuiInput inputControl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child controller - handles operations related to input panel.
|
||||||
|
* @param v   The Swing component for the input area
|
||||||
|
*/
|
||||||
|
public ControlInput(ViewInput v) {
|
||||||
|
view = v;
|
||||||
|
inputControl = new GuiInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds listeners to input area. */
|
||||||
|
public void addListeners() {
|
||||||
|
view.getBtnCancel().addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(final ActionEvent evt) {
|
||||||
|
btnCancelActionPerformed(evt);
|
||||||
|
view.getBtnOK().requestFocusInWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//
|
||||||
|
view.getBtnOK().addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(final ActionEvent evt) {
|
||||||
|
btnOKActionPerformed(evt);
|
||||||
|
|
||||||
|
if (AllZone.getPhase().isNeedToNextPhase()) {
|
||||||
|
// moves to next turn
|
||||||
|
AllZone.getPhase().setNeedToNextPhase(false);
|
||||||
|
AllZone.getPhase().nextPhase();
|
||||||
|
}
|
||||||
|
view.getBtnOK().requestFocusInWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//
|
||||||
|
view.getBtnOK().addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyPressed(final KeyEvent arg0) {
|
||||||
|
// TODO make triggers on escape
|
||||||
|
int code = arg0.getKeyCode();
|
||||||
|
if (code == KeyEvent.VK_ESCAPE) {
|
||||||
|
view.getBtnOK().doClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>btnCancelActionPerformed.</p>
|
||||||
|
* Triggers current cancel action from whichever input controller is being used.
|
||||||
|
*
|
||||||
|
* @param evt a {@link java.awt.event.ActionEvent} object.
|
||||||
|
*/
|
||||||
|
private void btnCancelActionPerformed(final ActionEvent evt) {
|
||||||
|
inputControl.selectButtonCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>btnOKActionPerformed.</p>
|
||||||
|
* Triggers current OK action from whichever input controller is being used.
|
||||||
|
*
|
||||||
|
* @param evt a {@link java.awt.event.ActionEvent} object.
|
||||||
|
*/
|
||||||
|
private void btnOKActionPerformed(final ActionEvent evt) {
|
||||||
|
inputControl.selectButtonOK();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return GuiInput */
|
||||||
|
public GuiInput getInputControl() {
|
||||||
|
return inputControl;
|
||||||
|
}
|
||||||
|
}
|
||||||
198
src/main/java/forge/control/match/ControlTabber.java
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
package forge.control.match;
|
||||||
|
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.GuiDisplayUtil;
|
||||||
|
import forge.MyObservable;
|
||||||
|
import forge.Singletons;
|
||||||
|
import forge.view.match.ViewTabber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the vertical tabber in sidebar used for
|
||||||
|
* viewing gameplay data: stack, combat, etc.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ControlTabber extends MyObservable {
|
||||||
|
private ViewTabber view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the vertical tabber in sidebar used for
|
||||||
|
* viewing gameplay data: stack, combat, etc.
|
||||||
|
*
|
||||||
|
* @param v   The tabber Swing component
|
||||||
|
*/
|
||||||
|
public ControlTabber(ViewTabber v) {
|
||||||
|
view = v;
|
||||||
|
if (Singletons.getModel().getPreferences().isMillingLossCondition()) {
|
||||||
|
view.getLblMilling().setEnabled(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
view.getLblMilling().setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Singletons.getModel().getPreferences().getHandView()) {
|
||||||
|
view.getLblHandView().setEnabled(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
view.getLblHandView().setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Singletons.getModel().getPreferences().getLibraryView()) {
|
||||||
|
view.getLblLibraryView().setEnabled(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
view.getLblLibraryView().setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds observers to tabber. */
|
||||||
|
public void addObservers() {
|
||||||
|
// Stack
|
||||||
|
Observer o1 = new Observer() {
|
||||||
|
public void update(final Observable a, final Object b) {
|
||||||
|
view.updateStack();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AllZone.getStack().addObserver(o1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds listeners to various components in tabber. */
|
||||||
|
public void addListeners() {
|
||||||
|
// Milling enable toggle
|
||||||
|
view.getLblMilling().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
view.getLblMilling().toggleEnabled();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// View any hand toggle
|
||||||
|
view.getLblHandView().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
view.getLblHandView().toggleEnabled();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// DevMode: View any library toggle
|
||||||
|
view.getLblLibraryView().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
view.getLblLibraryView().toggleEnabled();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// DevMode: Play unlimited land this turn toggle
|
||||||
|
view.getLblUnlimitedLands().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
GuiDisplayUtil.devModeUnlimitedLand();
|
||||||
|
|
||||||
|
// TODO: Enable toggle for this (e.g. Unlimited land each turn: enabled)
|
||||||
|
// Also must change enabled/disabled text in ViewTabber to reflect this.
|
||||||
|
//view.getLblUnlimitedLands().toggleEnabled();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// DevMode: Generate mana
|
||||||
|
view.getLblGenerateMana().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
GuiDisplayUtil.devModeGenerateMana();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// DevMode: Battlefield setup
|
||||||
|
view.getLblSetupGame().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
GuiDisplayUtil.devSetupGameState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// DevMode: Tutor for card
|
||||||
|
view.getLblTutor().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
GuiDisplayUtil.devModeTutor();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// DevMode: Add counter to permanent
|
||||||
|
view.getLblCounterPermanent().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
GuiDisplayUtil.devModeAddCounter();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// DevMode: Tap permanent
|
||||||
|
view.getLblTapPermanent().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
GuiDisplayUtil.devModeTapPerm();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// DevMode: Untap permanent
|
||||||
|
view.getLblUntapPermanent().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
GuiDisplayUtil.devModeUntapPerm();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// DevMode: Set human life
|
||||||
|
view.getLblHumanLife().addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
GuiDisplayUtil.devModeSetLife();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ViewTabber */
|
||||||
|
public ViewTabber getView() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Programatically forces card layout of sidebar tabber to show "Dev" panel.
|
||||||
|
*/
|
||||||
|
public void showPnlDev() {
|
||||||
|
view.getVtpTabber().showTab(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Programatically forces card layout of sidebar tabber to show "Players" panel.
|
||||||
|
*/
|
||||||
|
public void showPnlPlayers() {
|
||||||
|
view.getVtpTabber().showTab(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Programatically forces card layout of sidebar tabber to show "Console" panel.
|
||||||
|
*/
|
||||||
|
public void showPnlConsole() {
|
||||||
|
view.getVtpTabber().showTab(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Programatically forces card layout of sidebar tabber to show "Combat" panel.
|
||||||
|
*/
|
||||||
|
public void showPnlCombat() {
|
||||||
|
view.getVtpTabber().showTab(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Programatically forces card layout of sidebar tabber to show "Stack" panel.
|
||||||
|
*/
|
||||||
|
public void showPnlStack() {
|
||||||
|
view.getVtpTabber().showTab(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/main/java/forge/control/match/package-info.java
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
/** Child controllers used in match UI. */
|
||||||
|
package forge.control.match;
|
||||||
|
|
||||||
3
src/main/java/forge/control/package-info.java
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
/** Controller (as in model-view-controller) for Forge. */
|
||||||
|
package forge.control;
|
||||||
|
|
||||||
@@ -31,7 +31,14 @@ public class FButton extends JButton {
|
|||||||
private final AlphaComposite disabledComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.25f);
|
private final AlphaComposite disabledComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.25f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new f button.
|
* Instantiates a new FButton.
|
||||||
|
*/
|
||||||
|
public FButton() {
|
||||||
|
this("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new FButton.
|
||||||
*
|
*
|
||||||
* @param msg
|
* @param msg
|
||||||
* the msg
|
* the msg
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package forge.gui.skin;
|
|||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Image;
|
||||||
import java.awt.LayoutManager;
|
import java.awt.LayoutManager;
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
@@ -11,14 +12,15 @@ import javax.swing.JPanel;
|
|||||||
* <p>
|
* <p>
|
||||||
* FPanel.
|
* FPanel.
|
||||||
* </p>
|
* </p>
|
||||||
* The core JPanel used throughout the Forge project. Allows tiled images and
|
* The core JPanel used throughout the Forge project. Allows tiled texture images
|
||||||
* ...
|
* and single background images, using setBGTexture() and setBGImage() respectively.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class FPanel extends JPanel {
|
public class FPanel extends JPanel {
|
||||||
private ImageIcon bgImg = null;
|
private Image bgTexture, bgImg = null;
|
||||||
private int w, h, iw, ih, x, y = 0;
|
// Panel Width, panel Height, Image Width, Image Height, Image Aspect Ratio
|
||||||
|
private double w, h, iw, ih, iar, x, y = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new f panel.
|
* Instantiates a new f panel.
|
||||||
@@ -45,40 +47,84 @@ public class FPanel extends JPanel {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent(final Graphics g) {
|
protected void paintComponent(final Graphics g) {
|
||||||
// System.out.print("\nRepainting. ");
|
w = this.getWidth();
|
||||||
if (this.bgImg != null) {
|
h = this.getHeight();
|
||||||
this.w = this.getWidth();
|
|
||||||
this.h = this.getHeight();
|
|
||||||
this.iw = this.bgImg.getIconWidth();
|
|
||||||
this.ih = this.bgImg.getIconHeight();
|
|
||||||
|
|
||||||
while (this.x < this.w) {
|
// Draw background texture
|
||||||
while (this.y < this.h) {
|
if (bgTexture != null) {
|
||||||
g.drawImage(this.bgImg.getImage(), this.x, this.y, null);
|
iw = bgTexture.getWidth(null);
|
||||||
this.y += this.ih;
|
ih = bgTexture.getHeight(null);
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
|
||||||
|
while (x < w) {
|
||||||
|
while (y < h) {
|
||||||
|
g.drawImage(bgTexture, (int) x, (int) y, null);
|
||||||
|
y += ih;
|
||||||
}
|
}
|
||||||
this.x += this.iw;
|
x += iw;
|
||||||
this.y = 0;
|
y = 0;
|
||||||
|
}
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw background image
|
||||||
|
if (bgImg != null) {
|
||||||
|
iw = bgImg.getWidth(null); // Image Width
|
||||||
|
ih = bgImg.getHeight(null); // Image Height
|
||||||
|
iar = iw / ih; // Image Aspect Ratio
|
||||||
|
|
||||||
|
// Image is smaller than panel:
|
||||||
|
if (w > iw && h > ih) {
|
||||||
|
g.drawImage(bgImg, (int) (w - iw) / 2, (int) (h - ih) / 2, (int) iw, (int) ih, null);
|
||||||
|
}
|
||||||
|
// Image is larger than panel, and tall:
|
||||||
|
else if (iar < 1) {
|
||||||
|
g.drawImage(bgImg,
|
||||||
|
(int) ((w - h * iar) / 2), 0,
|
||||||
|
(int) ((w + h * iar) / 2), (int) h,
|
||||||
|
0, 0, (int) iw, (int) ih, null);
|
||||||
|
}
|
||||||
|
// Image is larger than panel, and wide:
|
||||||
|
else if (iar > 1) {
|
||||||
|
g.drawImage(bgImg,
|
||||||
|
0, (int) ((h - w / iar) / 2),
|
||||||
|
(int) w, (int) ((h + w / iar) / 2),
|
||||||
|
0, 0, (int) iw, (int) ih, null);
|
||||||
}
|
}
|
||||||
this.x = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the bG img.
|
* An FPanel can have a tiled texture and an image. The texture will be drawn
|
||||||
*
|
* first. If a background image has been set, it will be drawn on top of the
|
||||||
* @param icon
|
* texture, centered and scaled proportional to its aspect ratio.
|
||||||
* the new bG img
|
*
|
||||||
|
* @param i0   ImageIcon
|
||||||
*/
|
*/
|
||||||
public void setBGImg(final ImageIcon icon) {
|
public void setBGImg(final ImageIcon i0) {
|
||||||
this.bgImg = icon;
|
this.bgImg = i0.getImage();
|
||||||
if (this.bgImg != null) {
|
if (this.bgImg != null) {
|
||||||
this.setOpaque(false);
|
this.setOpaque(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An FPanel can have a tiled texture and an image. The texture will be drawn
|
||||||
|
* first. If a background image has been set, it will be drawn on top of the
|
||||||
|
* texture, centered and scaled proportional to its aspect ratio.
|
||||||
|
*
|
||||||
|
* @param i0   ImageIcon
|
||||||
|
*/
|
||||||
|
public void setBGTexture(final ImageIcon i0) {
|
||||||
|
this.bgTexture = i0.getImage();
|
||||||
|
if (this.bgTexture != null) {
|
||||||
|
this.setOpaque(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the preferred size.
|
* Sets the preferred size.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import forge.AllZone;
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class FRoundedPanel extends JPanel {
|
public class FRoundedPanel extends JPanel {
|
||||||
|
private boolean[] borders = { true, true, true, true };
|
||||||
private boolean[] corners = { true, true, true, true }; // NW, SW, SE, NE
|
private boolean[] corners = { true, true, true, true }; // NW, SW, SE, NE
|
||||||
private Color shadowColor = new Color(150, 150, 150, 150);
|
private Color shadowColor = new Color(150, 150, 150, 150);
|
||||||
private Color borderColor = AllZone.getSkin().getClrBorders();
|
private Color borderColor = AllZone.getSkin().getClrBorders();
|
||||||
@@ -146,39 +147,56 @@ public class FRoundedPanel extends JPanel {
|
|||||||
|
|
||||||
// Mid, left, right rectangles: border
|
// Mid, left, right rectangles: border
|
||||||
g2d.setColor(this.borderColor);
|
g2d.setColor(this.borderColor);
|
||||||
g2d.drawLine(r, 0, w - r - so, 0);
|
|
||||||
g2d.drawLine(r, h - so - 1, w - r - so, h - so - 1);
|
if (this.borders[0]) { g2d.drawLine(r, 0, w - r - so, 0); }
|
||||||
g2d.drawLine(0, r, 0, h - r - so);
|
if (this.borders[1]) { g2d.drawLine(0, r, 0, h - r - so); }
|
||||||
g2d.drawLine(w - so - 1, r, w - so - 1, h - r - so);
|
if (this.borders[2]) { g2d.drawLine(r, h - so - 1, w - r - so, h - so - 1); }
|
||||||
|
if (this.borders[3]) { g2d.drawLine(w - so - 1, r, w - so - 1, h - r - so); }
|
||||||
|
|
||||||
// Corners: border
|
// Corners: border
|
||||||
// NW
|
// NW
|
||||||
if (this.corners[0]) {
|
if (this.corners[0]) {
|
||||||
g2d.drawArc(0, 0, 2 * r, 2 * r, 90, 90);
|
g2d.drawArc(0, 0, 2 * r, 2 * r, 90, 90);
|
||||||
} else {
|
} else {
|
||||||
g2d.drawLine(0, 0, r, 0);
|
if (this.borders[0]) {
|
||||||
g2d.drawLine(0, 0, 0, r);
|
g2d.drawLine(0, 0, r, 0);
|
||||||
|
}
|
||||||
|
if (this.borders[1]) {
|
||||||
|
g2d.drawLine(0, 0, 0, r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// SW
|
// SW
|
||||||
if (this.corners[1]) {
|
if (this.corners[1]) {
|
||||||
g2d.drawArc(0, h - (2 * r) - so, 2 * r, (2 * r) - 1, 180, 90);
|
g2d.drawArc(0, h - (2 * r) - so, 2 * r, (2 * r) - 1, 180, 90);
|
||||||
} else {
|
} else {
|
||||||
g2d.drawLine(0, h - so - 1, 0, h - r - so - 1);
|
if (this.borders[1]) {
|
||||||
g2d.drawLine(0, h - so - 1, r, h - so - 1);
|
g2d.drawLine(0, h - so - 1, 0, h - r - so - 1);
|
||||||
|
}
|
||||||
|
if (this.borders[2]) {
|
||||||
|
g2d.drawLine(0, h - so - 1, r, h - so - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// SE
|
// SE
|
||||||
if (this.corners[2]) {
|
if (this.corners[2]) {
|
||||||
g2d.drawArc(w - (2 * r) - so, h - (2 * r) - so, (2 * r) - 1, (2 * r) - 1, 270, 90);
|
g2d.drawArc(w - (2 * r) - so, h - (2 * r) - so, (2 * r) - 1, (2 * r) - 1, 270, 90);
|
||||||
} else {
|
} else {
|
||||||
g2d.drawLine(w - so - 1, h - so - 1, w - so - 1, h - r - so);
|
if (this.borders[2]) {
|
||||||
g2d.drawLine(w - so - 1, h - so - 1, w - r - so, h - so - 1);
|
g2d.drawLine(w - so - 1, h - so - 1, w - r - so, h - so - 1);
|
||||||
|
}
|
||||||
|
if (this.borders[3]) {
|
||||||
|
g2d.drawLine(w - so - 1, h - so - 1, w - so - 1, h - r - so);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// NE
|
// NE
|
||||||
if (this.corners[3]) {
|
if (this.corners[3]) {
|
||||||
g2d.drawArc(w - (2 * r) - so, 0, (2 * r) - 1, (2 * r) - 1, 0, 90);
|
g2d.drawArc(w - (2 * r) - so, 0, (2 * r) - 1, (2 * r) - 1, 0, 90);
|
||||||
} else {
|
} else {
|
||||||
g2d.drawLine(w - so - 1, 0, w - so - r, 0);
|
if (this.borders[0]) {
|
||||||
g2d.drawLine(w - so - 1, 0, w - so - 1, r);
|
g2d.drawLine(w - so - 1, 0, w - so - r, 0);
|
||||||
|
}
|
||||||
|
if (this.borders[3]) {
|
||||||
|
g2d.drawLine(w - so - 1, 0, w - so - 1, r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,15 +248,14 @@ public class FRoundedPanel extends JPanel {
|
|||||||
* </p>
|
* </p>
|
||||||
* Sets radius of each corner on rounded panel.
|
* Sets radius of each corner on rounded panel.
|
||||||
*
|
*
|
||||||
* @param r
|
* @param r0   int
|
||||||
* the new corner radius
|
|
||||||
*/
|
*/
|
||||||
public void setCornerRadius(int r) {
|
public void setCornerRadius(int r0) {
|
||||||
if (r < 0) {
|
if (r0 < 0) {
|
||||||
r = 0;
|
r0 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cornerRadius = r;
|
this.cornerRadius = r0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -248,8 +265,7 @@ public class FRoundedPanel extends JPanel {
|
|||||||
* Sets if corners should be rounded or not in the following order: NW, SW,
|
* Sets if corners should be rounded or not in the following order: NW, SW,
|
||||||
* SE, NE
|
* SE, NE
|
||||||
*
|
*
|
||||||
* @param vals
|
* @param vals   boolean[4]
|
||||||
* the new corners
|
|
||||||
*/
|
*/
|
||||||
public void setCorners(final boolean[] vals) {
|
public void setCorners(final boolean[] vals) {
|
||||||
if (vals.length != 4) {
|
if (vals.length != 4) {
|
||||||
@@ -259,6 +275,23 @@ public class FRoundedPanel extends JPanel {
|
|||||||
this.corners = vals;
|
this.corners = vals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* setBorders.
|
||||||
|
* </p>
|
||||||
|
* Sets if borders should be displayed or not following order: N, W, S, E.
|
||||||
|
* Only works for square corners, rounded corners will be shown with borders.
|
||||||
|
*
|
||||||
|
* @param vals   boolean[4]
|
||||||
|
*/
|
||||||
|
public void setBorders(final boolean[] vals) {
|
||||||
|
if (vals.length != 4) {
|
||||||
|
throw new IllegalArgumentException("FRoundedPanel > setBorders requires an array of booleans of length 4.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.borders = vals;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the show shadow.
|
* Sets the show shadow.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ public class FSkin {
|
|||||||
/** Primary texture used in skin. */
|
/** Primary texture used in skin. */
|
||||||
private ImageIcon texture1 = null;
|
private ImageIcon texture1 = null;
|
||||||
|
|
||||||
|
/** Primary background image used during match play. */
|
||||||
|
private ImageIcon matchBG = null;
|
||||||
|
|
||||||
/** Left side of button, up state. */
|
/** Left side of button, up state. */
|
||||||
private ImageIcon btnLup = null;
|
private ImageIcon btnLup = null;
|
||||||
|
|
||||||
@@ -58,6 +61,17 @@ public class FSkin {
|
|||||||
/** Splash screen image. */
|
/** Splash screen image. */
|
||||||
private ImageIcon splash = null;
|
private ImageIcon splash = null;
|
||||||
|
|
||||||
|
/** Splash screen image. */
|
||||||
|
private ImageIcon icoEnabled = null;
|
||||||
|
private ImageIcon icoDisabled = null;
|
||||||
|
private ImageIcon icoTap = null;
|
||||||
|
private ImageIcon icoUntap = null;
|
||||||
|
private ImageIcon icoPlus = null;
|
||||||
|
private ImageIcon icoShortcuts = null;
|
||||||
|
private ImageIcon icoSettings = null;
|
||||||
|
private ImageIcon icoConcede = null;
|
||||||
|
private ImageIcon icoEndTurn = null;
|
||||||
|
|
||||||
/** Base color used in skin. */
|
/** Base color used in skin. */
|
||||||
private Color clrTheme = Color.red;
|
private Color clrTheme = Color.red;
|
||||||
|
|
||||||
@@ -95,7 +109,7 @@ public class FSkin {
|
|||||||
private String name = "default";
|
private String name = "default";
|
||||||
|
|
||||||
// ===== Private fields
|
// ===== Private fields
|
||||||
private final String paletteFile = "palette.png";
|
private final String spriteFile = "sprite.png";
|
||||||
private final String font1file = "font1.ttf";
|
private final String font1file = "font1.ttf";
|
||||||
private final String font2file = "font2.ttf";
|
private final String font2file = "font2.ttf";
|
||||||
private final String texture1file = "texture1.jpg";
|
private final String texture1file = "texture1.jpg";
|
||||||
@@ -109,11 +123,11 @@ public class FSkin {
|
|||||||
private final String btnMdownfile = "btnMdown.png";
|
private final String btnMdownfile = "btnMdown.png";
|
||||||
private final String btnRdownfile = "btnRdown.png";
|
private final String btnRdownfile = "btnRdown.png";
|
||||||
private final String splashfile = "bg_splash.jpg";
|
private final String splashfile = "bg_splash.jpg";
|
||||||
|
private final String matchfile = "bg_match.jpg";
|
||||||
|
|
||||||
private ImageIcon tempImg;
|
private ImageIcon tempImg;
|
||||||
private Font tempFont;
|
private Font tempFont;
|
||||||
private String skin;
|
private final String notfound = "FSkin.java: Can't find ";
|
||||||
private final String notfound = "FSkin.java: \"" + this.skin + "\" skin can't find ";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FSkin constructor. No arguments, will generate default skin settings,
|
* FSkin constructor. No arguments, will generate default skin settings,
|
||||||
@@ -153,6 +167,7 @@ public class FSkin {
|
|||||||
|
|
||||||
// Images
|
// Images
|
||||||
this.setTexture1(this.retrieveImage(dirName + this.texture1file));
|
this.setTexture1(this.retrieveImage(dirName + this.texture1file));
|
||||||
|
this.setMatchBG(this.retrieveImage(dirName + this.matchfile));
|
||||||
this.setBtnLup(this.retrieveImage(dirName + this.btnLupfile));
|
this.setBtnLup(this.retrieveImage(dirName + this.btnLupfile));
|
||||||
this.setBtnMup(this.retrieveImage(dirName + this.btnMupfile));
|
this.setBtnMup(this.retrieveImage(dirName + this.btnMupfile));
|
||||||
this.setBtnRup(this.retrieveImage(dirName + this.btnRupfile));
|
this.setBtnRup(this.retrieveImage(dirName + this.btnRupfile));
|
||||||
@@ -162,26 +177,35 @@ public class FSkin {
|
|||||||
this.setBtnLdown(this.retrieveImage(dirName + this.btnLdownfile));
|
this.setBtnLdown(this.retrieveImage(dirName + this.btnLdownfile));
|
||||||
this.setBtnMdown(this.retrieveImage(dirName + this.btnMdownfile));
|
this.setBtnMdown(this.retrieveImage(dirName + this.btnMdownfile));
|
||||||
this.setBtnRdown(this.retrieveImage(dirName + this.btnRdownfile));
|
this.setBtnRdown(this.retrieveImage(dirName + this.btnRdownfile));
|
||||||
this.setSplash(this.retrieveImage(dirName + this.splashfile));
|
this.setSplashBG(this.retrieveImage(dirName + this.splashfile));
|
||||||
|
|
||||||
// Color palette
|
// Color palette
|
||||||
final File file = new File(dirName + this.paletteFile);
|
final File file = new File(dirName + this.spriteFile);
|
||||||
BufferedImage image;
|
BufferedImage image;
|
||||||
try {
|
try {
|
||||||
image = ImageIO.read(file);
|
image = ImageIO.read(file);
|
||||||
this.setClrTheme(this.getColorFromPixel(image.getRGB(60, 10)));
|
this.setClrTheme(this.getColorFromPixel(image.getRGB(70, 10)));
|
||||||
this.setClrBorders(this.getColorFromPixel(image.getRGB(60, 30)));
|
this.setClrBorders(this.getColorFromPixel(image.getRGB(70, 30)));
|
||||||
this.setClrZebra(this.getColorFromPixel(image.getRGB(60, 50)));
|
this.setClrZebra(this.getColorFromPixel(image.getRGB(70, 50)));
|
||||||
this.setClrHover(this.getColorFromPixel(image.getRGB(60, 70)));
|
this.setClrHover(this.getColorFromPixel(image.getRGB(70, 70)));
|
||||||
this.setClrActive(this.getColorFromPixel(image.getRGB(60, 90)));
|
this.setClrActive(this.getColorFromPixel(image.getRGB(70, 90)));
|
||||||
this.setClrInactive(this.getColorFromPixel(image.getRGB(60, 110)));
|
this.setClrInactive(this.getColorFromPixel(image.getRGB(70, 110)));
|
||||||
this.setClrText(this.getColorFromPixel(image.getRGB(60, 130)));
|
this.setClrText(this.getColorFromPixel(image.getRGB(70, 130)));
|
||||||
this.setClrProgress1(this.getColorFromPixel(image.getRGB(55, 145)));
|
this.setClrProgress1(this.getColorFromPixel(image.getRGB(65, 145)));
|
||||||
this.setClrProgress2(this.getColorFromPixel(image.getRGB(65, 145)));
|
this.setClrProgress2(this.getColorFromPixel(image.getRGB(75, 145)));
|
||||||
this.setClrProgress3(this.getColorFromPixel(image.getRGB(55, 155)));
|
this.setClrProgress3(this.getColorFromPixel(image.getRGB(65, 155)));
|
||||||
this.setClrProgress4(this.getColorFromPixel(image.getRGB(65, 155)));
|
this.setClrProgress4(this.getColorFromPixel(image.getRGB(75, 155)));
|
||||||
|
this.setIconEnabled(image.getSubimage(80, 0, 40, 40));
|
||||||
|
this.setIconDisabled(image.getSubimage(120, 0, 40, 40));
|
||||||
|
this.setIconTap(image.getSubimage(80, 40, 40, 40));
|
||||||
|
this.setIconUntap(image.getSubimage(120, 40, 40, 40));
|
||||||
|
this.setIconPlus(image.getSubimage(80, 80, 40, 40));
|
||||||
|
this.setIconShortcuts(image.getSubimage(160, 0, 80, 80));
|
||||||
|
this.setIconEndTurn(image.getSubimage(160, 80, 80, 80));
|
||||||
|
this.setIconSettings(image.getSubimage(80, 0, 80, 80));
|
||||||
|
this.setIconConcede(image.getSubimage(80, 80, 80, 80));
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
System.err.println(this.notfound + this.paletteFile);
|
System.err.println(this.notfound + this.spriteFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -273,7 +297,7 @@ public class FSkin {
|
|||||||
* Splash screen image.
|
* Splash screen image.
|
||||||
* @return {@link javax.swing.ImageIcon} splash
|
* @return {@link javax.swing.ImageIcon} splash
|
||||||
*/
|
*/
|
||||||
public ImageIcon getSplash() {
|
public ImageIcon getSplashBG() {
|
||||||
return splash;
|
return splash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +305,7 @@ public class FSkin {
|
|||||||
* Splash screen image.
|
* Splash screen image.
|
||||||
* @param splash0   an image icon
|
* @param splash0   an image icon
|
||||||
*/
|
*/
|
||||||
public void setSplash(ImageIcon splash0) {
|
public void setSplashBG(ImageIcon splash0) {
|
||||||
this.splash = splash0;
|
this.splash = splash0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,6 +357,22 @@ public class FSkin {
|
|||||||
this.texture1 = texture10;
|
this.texture1 = texture10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primary background image used during match play.
|
||||||
|
* @return ImageIcon
|
||||||
|
*/
|
||||||
|
public ImageIcon getMatchBG() {
|
||||||
|
return matchBG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primary background image used during match play.
|
||||||
|
* @param img0   an image icon
|
||||||
|
*/
|
||||||
|
public void setMatchBG(ImageIcon img0) {
|
||||||
|
this.matchBG = img0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Color of zebra striping in grid displays.
|
* Color of zebra striping in grid displays.
|
||||||
* @return {@link java.awt.Color} clrZebra
|
* @return {@link java.awt.Color} clrZebra
|
||||||
@@ -626,4 +666,94 @@ public class FSkin {
|
|||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @param bi0   BufferedImage */
|
||||||
|
public void setIconEnabled(BufferedImage bi0) {
|
||||||
|
this.icoEnabled = new ImageIcon(bi0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ImageIcon */
|
||||||
|
public ImageIcon getIconEnabled() {
|
||||||
|
return icoEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param bi0   BufferedImage */
|
||||||
|
public void setIconDisabled(BufferedImage bi0) {
|
||||||
|
this.icoDisabled = new ImageIcon(bi0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ImageIcon */
|
||||||
|
public ImageIcon getIconDisabled() {
|
||||||
|
return icoDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param bi0   BufferedImage */
|
||||||
|
public void setIconTap(BufferedImage bi0) {
|
||||||
|
this.icoTap = new ImageIcon(bi0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ImageIcon */
|
||||||
|
public ImageIcon getIconTap() {
|
||||||
|
return icoTap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param bi0   BufferedImage */
|
||||||
|
public void setIconUntap(BufferedImage bi0) {
|
||||||
|
this.icoUntap = new ImageIcon(bi0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ImageIcon */
|
||||||
|
public ImageIcon getIconUntap() {
|
||||||
|
return icoUntap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param bi0   BufferedImage */
|
||||||
|
public void setIconPlus(BufferedImage bi0) {
|
||||||
|
this.icoPlus = new ImageIcon(bi0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ImageIcon */
|
||||||
|
public ImageIcon getIconPlus() {
|
||||||
|
return icoPlus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param bi0   BufferedImage */
|
||||||
|
public void setIconShortcuts(BufferedImage bi0) {
|
||||||
|
this.icoShortcuts = new ImageIcon(bi0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ImageIcon */
|
||||||
|
public ImageIcon getIconShortcuts() {
|
||||||
|
return icoShortcuts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param bi0   BufferedImage */
|
||||||
|
public void setIconSettings(BufferedImage bi0) {
|
||||||
|
this.icoSettings = new ImageIcon(bi0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ImageIcon */
|
||||||
|
public ImageIcon getIconSettings() {
|
||||||
|
return icoSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param bi0   BufferedImage */
|
||||||
|
public void setIconConcede(BufferedImage bi0) {
|
||||||
|
this.icoConcede = new ImageIcon(bi0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ImageIcon */
|
||||||
|
public ImageIcon getIconConcede() {
|
||||||
|
return icoConcede;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param bi0   BufferedImage */
|
||||||
|
public void setIconEndTurn(BufferedImage bi0) {
|
||||||
|
this.icoEndTurn = new ImageIcon(bi0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ImageIcon */
|
||||||
|
public ImageIcon getIconEndTurn() {
|
||||||
|
return icoEndTurn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ public class FGameState {
|
|||||||
* the phase to set
|
* the phase to set
|
||||||
*/
|
*/
|
||||||
protected final void setPhase(final Phase phase0) {
|
protected final void setPhase(final Phase phase0) {
|
||||||
|
System.out.println("asdf:"+phase0);
|
||||||
this.phase = phase0;
|
this.phase = phase0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class ForgePreferences extends Preferences {
|
public class ForgePreferences extends Preferences {
|
||||||
|
|
||||||
/** The new gui. */
|
/** Old gui checkbox toggle. */
|
||||||
private final boolean newGui;
|
private boolean oldGui;
|
||||||
|
|
||||||
/** The stack ai land. */
|
/** The stack ai land. */
|
||||||
private boolean stackAiLand;
|
private boolean stackAiLand;
|
||||||
@@ -27,7 +27,13 @@ public class ForgePreferences extends Preferences {
|
|||||||
/** The milling loss condition. */
|
/** The milling loss condition. */
|
||||||
private boolean millingLossCondition;
|
private boolean millingLossCondition;
|
||||||
|
|
||||||
/** The developer mode. */
|
/** Hand view toggle. */
|
||||||
|
private boolean handView;
|
||||||
|
|
||||||
|
/** Library view toggle. */
|
||||||
|
private boolean libraryView;
|
||||||
|
|
||||||
|
/** Developer mode. */
|
||||||
private boolean developerMode;
|
private boolean developerMode;
|
||||||
|
|
||||||
/** The upload draft ai. */
|
/** The upload draft ai. */
|
||||||
@@ -106,6 +112,17 @@ public class ForgePreferences extends Preferences {
|
|||||||
/** The b human end combat. */
|
/** The b human end combat. */
|
||||||
private boolean bHumanEndCombat;
|
private boolean bHumanEndCombat;
|
||||||
|
|
||||||
|
// Keyboard shortcuts
|
||||||
|
private String showStackShortcut;
|
||||||
|
private String showCombatShortcut;
|
||||||
|
private String showConsoleShortcut;
|
||||||
|
private String showPlayersShortcut;
|
||||||
|
private String showDevShortcut;
|
||||||
|
private String concedeShortcut;
|
||||||
|
private String showPictureShortcut;
|
||||||
|
private String showDetailShortcut;
|
||||||
|
|
||||||
|
//
|
||||||
private final List<SavePreferencesListener> saveListeners = new ArrayList<SavePreferencesListener>();
|
private final List<SavePreferencesListener> saveListeners = new ArrayList<SavePreferencesListener>();
|
||||||
private final String fileName;
|
private final String fileName;
|
||||||
|
|
||||||
@@ -135,9 +152,11 @@ public class ForgePreferences extends Preferences {
|
|||||||
throw new Exception("Error reading \"" + fileName + "\".", ex);
|
throw new Exception("Error reading \"" + fileName + "\".", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.newGui = this.getBoolean("gui.new", true);
|
this.oldGui = this.getBoolean("gui.old", true);
|
||||||
this.setStackAiLand(this.getBoolean("AI.stack.land", false));
|
this.setStackAiLand(this.getBoolean("AI.stack.land", false));
|
||||||
this.setMillingLossCondition(this.getBoolean("loss.condition.milling", true));
|
this.setMillingLossCondition(this.getBoolean("loss.condition.milling", true));
|
||||||
|
this.setHandView(this.getBoolean("developer.handview", true));
|
||||||
|
this.setLibraryView(this.getBoolean("developer.libraryview", true));
|
||||||
this.setDeveloperMode(this.getBoolean("developer.mode", false));
|
this.setDeveloperMode(this.getBoolean("developer.mode", false));
|
||||||
|
|
||||||
this.setUploadDraftAI(this.getBoolean("upload.Draft.AI", true));
|
this.setUploadDraftAI(this.getBoolean("upload.Draft.AI", true));
|
||||||
@@ -172,6 +191,16 @@ public class ForgePreferences extends Preferences {
|
|||||||
this.setbHumanEOT(this.getBoolean("phase.human.eot", true));
|
this.setbHumanEOT(this.getBoolean("phase.human.eot", true));
|
||||||
this.setbHumanBeginCombat(this.getBoolean("phase.human.beginCombat", true));
|
this.setbHumanBeginCombat(this.getBoolean("phase.human.beginCombat", true));
|
||||||
this.setbHumanEndCombat(this.getBoolean("phase.human.endCombat", true));
|
this.setbHumanEndCombat(this.getBoolean("phase.human.endCombat", true));
|
||||||
|
|
||||||
|
// Keyboard shortcuts
|
||||||
|
this.setShowStackShortcut(this.get("shortcut.showstack", "83"));
|
||||||
|
this.setShowCombatShortcut(this.get("shortcut.showcombat", "67"));
|
||||||
|
this.setShowConsoleShortcut(this.get("shortcut.showconsole", "76"));
|
||||||
|
this.setShowPlayersShortcut(this.get("shortcut.showplayers", "80"));
|
||||||
|
this.setShowDevShortcut(this.get("shortcut.showdev", "68"));
|
||||||
|
this.setConcedeShortcut(this.get("shortcut.concede", "27"));
|
||||||
|
this.setShowPictureShortcut(this.get("shortcut.showpicture", "17 80"));
|
||||||
|
this.setShowDetailShortcut(this.get("shortcut.showdetail", "17 68"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -184,10 +213,12 @@ public class ForgePreferences extends Preferences {
|
|||||||
*/
|
*/
|
||||||
public final void save() throws Exception {
|
public final void save() throws Exception {
|
||||||
|
|
||||||
this.set("gui.new", this.newGui);
|
this.set("gui.old", this.oldGui);
|
||||||
|
|
||||||
this.set("AI.stack.land", this.isStackAiLand());
|
this.set("AI.stack.land", this.isStackAiLand());
|
||||||
this.set("loss.condition.milling", this.isMillingLossCondition());
|
this.set("loss.condition.milling", this.isMillingLossCondition());
|
||||||
|
this.set("developer.handview", this.getHandView());
|
||||||
|
this.set("developer.libraryview", this.getLibraryView());
|
||||||
this.set("developer.mode", this.isDeveloperMode());
|
this.set("developer.mode", this.isDeveloperMode());
|
||||||
this.set("upload.Draft.AI", this.isUploadDraftAI());
|
this.set("upload.Draft.AI", this.isUploadDraftAI());
|
||||||
|
|
||||||
@@ -224,6 +255,16 @@ public class ForgePreferences extends Preferences {
|
|||||||
this.set("phase.human.beginCombat", this.isbHumanBeginCombat());
|
this.set("phase.human.beginCombat", this.isbHumanBeginCombat());
|
||||||
this.set("phase.human.endCombat", this.isbHumanEndCombat());
|
this.set("phase.human.endCombat", this.isbHumanEndCombat());
|
||||||
|
|
||||||
|
// Keyboard shortcuts
|
||||||
|
this.set("shortcut.showstack", this.getShowStackShortcut());
|
||||||
|
this.set("shortcut.showcombat", this.getShowCombatShortcut());
|
||||||
|
this.set("shortcut.showconsole", this.getShowConsoleShortcut());
|
||||||
|
this.set("shortcut.showplayers", this.getShowPlayersShortcut());
|
||||||
|
this.set("shortcut.showdev", this.getShowDevShortcut());
|
||||||
|
this.set("shortcut.concede", this.getConcedeShortcut());
|
||||||
|
this.set("shortcut.showpicture", this.getShowPictureShortcut());
|
||||||
|
this.set("shortcut.showdetail", this.getShowDetailShortcut());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final FileOutputStream stream = new FileOutputStream(this.fileName);
|
final FileOutputStream stream = new FileOutputStream(this.fileName);
|
||||||
this.store(stream, "Forge");
|
this.store(stream, "Forge");
|
||||||
@@ -248,7 +289,7 @@ public class ForgePreferences extends Preferences {
|
|||||||
/**
|
/**
|
||||||
* Checks if is stack ai land.
|
* Checks if is stack ai land.
|
||||||
*
|
*
|
||||||
* @return the stackAiLand
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public boolean isStackAiLand() {
|
public boolean isStackAiLand() {
|
||||||
return this.stackAiLand;
|
return this.stackAiLand;
|
||||||
@@ -257,29 +298,78 @@ public class ForgePreferences extends Preferences {
|
|||||||
/**
|
/**
|
||||||
* Sets the stack ai land.
|
* Sets the stack ai land.
|
||||||
*
|
*
|
||||||
* @param stackAiLand the stackAiLand to set
|
* @param b0   boolean
|
||||||
*/
|
*/
|
||||||
public void setStackAiLand(final boolean stackAiLand) {
|
public void setStackAiLand(final boolean b0) {
|
||||||
this.stackAiLand = stackAiLand; // TODO: Add 0 to parameter's name.
|
this.stackAiLand = b0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if is milling loss condition.
|
* Checks if old gui is to be used.
|
||||||
*
|
*
|
||||||
* @return the millingLossCondition
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean isOldGui() {
|
||||||
|
return this.oldGui;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets if old gui is to be used.
|
||||||
|
*
|
||||||
|
* @param b0   boolean
|
||||||
|
*/
|
||||||
|
public void setOldGui(final boolean b0) {
|
||||||
|
this.oldGui = b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if loss by milling is enabled.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public boolean isMillingLossCondition() {
|
public boolean isMillingLossCondition() {
|
||||||
return this.millingLossCondition;
|
return this.millingLossCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the milling loss condition.
|
* Sets if loss by milling is enabled.
|
||||||
*
|
*
|
||||||
* @param millingLossCondition the millingLossCondition to set
|
* @param millingLossCondition0 the millingLossCondition to set
|
||||||
*/
|
*/
|
||||||
public void setMillingLossCondition(final boolean millingLossCondition) {
|
public void setMillingLossCondition(final boolean millingLossCondition0) {
|
||||||
this.millingLossCondition = millingLossCondition; // TODO: Add 0 to
|
this.millingLossCondition = millingLossCondition0;
|
||||||
// parameter's name.
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if "view any hand" option in dev mode is enabled or not.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean getHandView() {
|
||||||
|
return this.handView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if "view any hand" option in dev mode is enabled or not.
|
||||||
|
* @param b0   boolean
|
||||||
|
*/
|
||||||
|
public void setHandView(final boolean b0) {
|
||||||
|
this.handView = b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if "view any library" option in dev mode is enabled or not.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean getLibraryView() {
|
||||||
|
return this.libraryView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if "view any library" option in dev mode is enabled or not.
|
||||||
|
* @param b0   boolean
|
||||||
|
*/
|
||||||
|
public void setLibraryView(final boolean b0) {
|
||||||
|
this.libraryView = b0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -791,4 +881,85 @@ public class ForgePreferences extends Preferences {
|
|||||||
/** The large. */
|
/** The large. */
|
||||||
large
|
large
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keyboard shortcuts
|
||||||
|
/** @return String   String of keycodes set for this shortcut, delimited with spaces. */
|
||||||
|
public String getShowStackShortcut() {
|
||||||
|
return this.showStackShortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param keycodes   String of keycodes to set for this shortcut, delimited with spaces. */
|
||||||
|
public void setShowStackShortcut(String keycodes) {
|
||||||
|
this.showStackShortcut = keycodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return String   String of keycodes set for this shortcut, delimited with spaces. */
|
||||||
|
public String getShowCombatShortcut() {
|
||||||
|
return this.showCombatShortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param keycodes   String of keycodes to set for this shortcut, delimited with spaces. */
|
||||||
|
public void setShowCombatShortcut(String keycodes) {
|
||||||
|
this.showCombatShortcut = keycodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return String   String of keycodes set for this shortcut, delimited with spaces. */
|
||||||
|
public String getShowConsoleShortcut() {
|
||||||
|
return this.showConsoleShortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param keycodes   String of keycodes to set for this shortcut, delimited with spaces. */
|
||||||
|
public void setShowConsoleShortcut(String keycodes) {
|
||||||
|
this.showConsoleShortcut = keycodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return String   String of keycodes set for this shortcut, delimited with spaces. */
|
||||||
|
public String getShowPlayersShortcut() {
|
||||||
|
return this.showPlayersShortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param keycodes   String of keycodes to set for this shortcut, delimited with spaces. */
|
||||||
|
public void setShowPlayersShortcut(String keycodes) {
|
||||||
|
this.showPlayersShortcut = keycodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return String   String of keycodes set for this shortcut, delimited with spaces. */
|
||||||
|
public String getShowDevShortcut() {
|
||||||
|
return this.showDevShortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param keycodes   String of keycodes to set for this shortcut, delimited with spaces. */
|
||||||
|
public void setShowDevShortcut(String keycodes) {
|
||||||
|
this.showDevShortcut = keycodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return String   String of keycodes set for this shortcut, delimited with spaces. */
|
||||||
|
public String getConcedeShortcut() {
|
||||||
|
return this.concedeShortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param keycodes   String of keycodes to set for this shortcut, delimited with spaces. */
|
||||||
|
public void setConcedeShortcut(String keycodes) {
|
||||||
|
this.concedeShortcut = keycodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return String   String of keycodes set for this shortcut, delimited with spaces. */
|
||||||
|
public String getShowPictureShortcut() {
|
||||||
|
return this.showPictureShortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param keycodes   String of keycodes to set for this shortcut, delimited with spaces. */
|
||||||
|
public void setShowPictureShortcut(String keycodes) {
|
||||||
|
this.showPictureShortcut = keycodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return String   String of keycodes set for this shortcut, delimited with spaces. */
|
||||||
|
public String getShowDetailShortcut() {
|
||||||
|
return this.showDetailShortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param keycodes   String of keycodes to set for this shortcut, delimited with spaces. */
|
||||||
|
public void setShowDetailShortcut(String keycodes) {
|
||||||
|
this.showDetailShortcut = keycodes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -760,7 +760,7 @@ public final class NewConstants {
|
|||||||
public static final String DECK_EDITOR = "%s/NewGame/deckeditor";
|
public static final String DECK_EDITOR = "%s/NewGame/deckeditor";
|
||||||
|
|
||||||
/** The NE w_ gui. */
|
/** The NE w_ gui. */
|
||||||
public static final String NEW_GUI = "%s/NewGame/newgui";
|
public static final String OLD_GUI = "%s/NewGame/oldgui";
|
||||||
|
|
||||||
/** The A i_ land. */
|
/** The A i_ land. */
|
||||||
public static final String AI_LAND = "%s/NewGame/ailand";
|
public static final String AI_LAND = "%s/NewGame/ailand";
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import forge.Command;
|
|||||||
import forge.Constant;
|
import forge.Constant;
|
||||||
import forge.GuiDisplay;
|
import forge.GuiDisplay;
|
||||||
import forge.ImageCache;
|
import forge.ImageCache;
|
||||||
|
import forge.control.ControlAllUI;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.gui.GuiUtils;
|
import forge.gui.GuiUtils;
|
||||||
import forge.gui.deckeditor.DeckEditorQuest;
|
import forge.gui.deckeditor.DeckEditorQuest;
|
||||||
@@ -755,13 +756,14 @@ public class QuestMainPanel extends QuestAbstractPanel {
|
|||||||
// Dev Mode occurs before Display
|
// Dev Mode occurs before Display
|
||||||
Constant.Runtime.DEV_MODE[0] = this.devModeCheckBox.isSelected();
|
Constant.Runtime.DEV_MODE[0] = this.devModeCheckBox.isSelected();
|
||||||
|
|
||||||
// DO NOT CHANGE THIS ORDER, GuiDisplay needs to be created before cards
|
if (Constant.Runtime.OLDGUI[0]) {
|
||||||
// are added
|
AllZone.setDisplay(new GuiDisplay());
|
||||||
// if (newGUICheckbox.isSelected()) {
|
}
|
||||||
AllZone.setDisplay(new GuiDisplay());
|
else {
|
||||||
// } else {
|
ControlAllUI ui = new ControlAllUI();
|
||||||
// AllZone.setDisplay(new GuiDisplay3());
|
AllZone.setDisplay(ui.getMatchView());
|
||||||
// }
|
ui.getMatchController().initMatch();
|
||||||
|
}
|
||||||
|
|
||||||
Constant.Runtime.SMOOTH[0] = this.smoothLandCheckBox.isSelected();
|
Constant.Runtime.SMOOTH[0] = this.smoothLandCheckBox.isSelected();
|
||||||
|
|
||||||
|
|||||||
49
src/main/java/forge/view/GuiTopLevel.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package forge.view;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLayeredPane;
|
||||||
|
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.view.toolbox.FOverlay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent JFrame for Forge UI.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class GuiTopLevel extends JFrame {
|
||||||
|
private JLayeredPane lpnContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent JFrame for Forge UI.
|
||||||
|
*/
|
||||||
|
public GuiTopLevel() {
|
||||||
|
super();
|
||||||
|
setMinimumSize(new Dimension(800, 600));
|
||||||
|
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH);
|
||||||
|
|
||||||
|
lpnContent = new JLayeredPane();
|
||||||
|
lpnContent.setOpaque(true);
|
||||||
|
setContentPane(lpnContent);
|
||||||
|
addOverlay();
|
||||||
|
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds overlay panel to modal layer. Used when removeAll()
|
||||||
|
* has been called on the JLayeredPane parent.
|
||||||
|
*/
|
||||||
|
public void addOverlay() {
|
||||||
|
final FOverlay pnlOverlay = new FOverlay();
|
||||||
|
AllZone.setOverlay(pnlOverlay);
|
||||||
|
pnlOverlay.setOpaque(false);
|
||||||
|
pnlOverlay.setVisible(false);
|
||||||
|
pnlOverlay.setBounds(0, 0, getWidth(), getHeight());
|
||||||
|
lpnContent.add(pnlOverlay, JLayeredPane.MODAL_LAYER);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/main/java/forge/view/home/HomeTopLevel.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package forge.view.home;
|
||||||
|
|
||||||
|
import forge.gui.skin.FPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lays out battle, sidebar, user areas in locked % vals and repaints
|
||||||
|
* as necessary.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class HomeTopLevel extends FPanel {
|
||||||
|
public HomeTopLevel() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
52
src/main/java/forge/view/match/ViewAreaBattlefield.java
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package forge.view.match;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.gui.skin.FPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Battlefield, assembles and contains instances of MatchPlayer.
|
||||||
|
* SHOULD PROBABLY COLLAPSE INTO TOP LEVEL.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ViewAreaBattlefield extends FPanel {
|
||||||
|
private List<ViewField> fields;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An FPanel that adds instances of ViewField fields
|
||||||
|
* from player name list.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ViewAreaBattlefield() {
|
||||||
|
super();
|
||||||
|
setOpaque(false);
|
||||||
|
setLayout(new MigLayout("wrap, insets 1% 0.5% 0 0, gap 1%, nocache"));
|
||||||
|
|
||||||
|
// When future codebase upgrades allow, as many fields as
|
||||||
|
// necessary can be instantiated here. Doublestrike 29-10-11
|
||||||
|
|
||||||
|
fields = new ArrayList<ViewField>();
|
||||||
|
|
||||||
|
ViewField temp;
|
||||||
|
|
||||||
|
temp = new ViewField(AllZone.getComputerPlayer());
|
||||||
|
this.add(temp, "h 48.5%!, w 99.5%!");
|
||||||
|
fields.add(temp);
|
||||||
|
|
||||||
|
temp = new ViewField(AllZone.getHumanPlayer());
|
||||||
|
this.add(temp, "h 48.5%!, w 99.5%!");
|
||||||
|
fields.add(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of field components in battlefield.
|
||||||
|
* @return List<ViewFields>
|
||||||
|
*/
|
||||||
|
public List<ViewField> getFields() {
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/main/java/forge/view/match/ViewAreaSidebar.java
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package forge.view.match;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.gui.skin.FPanel;
|
||||||
|
import forge.gui.skin.FRoundedPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles display of child components of sidebar area in match UI.
|
||||||
|
* SHOULD PROBABLY COLLAPSE INTO TOP LEVEL.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ViewAreaSidebar extends FPanel {
|
||||||
|
private ViewCardviewer cardviewer;
|
||||||
|
private ViewTabber tabber;
|
||||||
|
private FRoundedPanel sidebar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles display of all components of sidebar area in match UI.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ViewAreaSidebar() {
|
||||||
|
super();
|
||||||
|
setOpaque(false);
|
||||||
|
setLayout(new MigLayout("insets 0"));
|
||||||
|
sidebar = new FRoundedPanel();
|
||||||
|
sidebar.setLayout(new MigLayout("wrap, gap 0, insets 0"));
|
||||||
|
sidebar.setBackground(AllZone.getSkin().getClrTheme());
|
||||||
|
sidebar.setCorners(new boolean[] {true, true, false, false});
|
||||||
|
|
||||||
|
// Add tabber, cardview, and finally sidebar. Unfortunately,
|
||||||
|
// tabber and cardviewer cannot extend FVerticalTabPanel, since that
|
||||||
|
// requires child panels to be prepared before it's instantiated.
|
||||||
|
// Therefore, their vertical tab panels must be accessed indirectly via
|
||||||
|
// an instance of this class.
|
||||||
|
cardviewer = new ViewCardviewer();
|
||||||
|
tabber = new ViewTabber();
|
||||||
|
|
||||||
|
sidebar.add(cardviewer.getVtpCardviewer(), "w 97%!, h 40%!, gapleft 1%, gapright 2%");
|
||||||
|
sidebar.add(tabber.getVtpTabber(), "w 97%!, h 60%!, gapright 2%");
|
||||||
|
add(sidebar, "h 98%!, w 98%!, gapleft 2%, gaptop 1%");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves vertical tab panel used for card picture and detail.
|
||||||
|
*
|
||||||
|
* @return ViewCardviewer vertical tab panel
|
||||||
|
*/
|
||||||
|
public ViewCardviewer getCardviewer() {
|
||||||
|
return cardviewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves vertical tab panel used for data presentation.
|
||||||
|
*
|
||||||
|
* @return ViewTabber vertical tab panel
|
||||||
|
*/
|
||||||
|
public ViewTabber getTabber() {
|
||||||
|
return tabber;
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/main/java/forge/view/match/ViewAreaUser.java
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package forge.view.match;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import forge.gui.skin.FPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent panel for display of input, hand, and dock.
|
||||||
|
* SHOULD PROBABLY COLLAPSE INTO TOP LEVEL.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ViewAreaUser extends FPanel {
|
||||||
|
private ViewDock pnlDock;
|
||||||
|
private ViewHand pnlHand;
|
||||||
|
|
||||||
|
private JPanel pnlMessage;
|
||||||
|
private ViewInput pnlInput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assembles user area of match UI.
|
||||||
|
*/
|
||||||
|
public ViewAreaUser() {
|
||||||
|
super();
|
||||||
|
setOpaque(false);
|
||||||
|
setLayout(new MigLayout("fill, insets 0, gap 0"));
|
||||||
|
|
||||||
|
// Input panel
|
||||||
|
pnlInput = new ViewInput();
|
||||||
|
|
||||||
|
// Hand panel
|
||||||
|
pnlHand = new ViewHand();
|
||||||
|
|
||||||
|
// Dock panel
|
||||||
|
pnlDock = new ViewDock();
|
||||||
|
|
||||||
|
// A.D.D.
|
||||||
|
add(pnlInput, "h 100%!, west, w 200px!");
|
||||||
|
add(pnlHand, "grow, gapleft 5");
|
||||||
|
add(pnlDock, "growx, h 50px!, south, gaptop 5, gapleft 5");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ViewDock */
|
||||||
|
public ViewDock getPnlDock() {
|
||||||
|
return pnlDock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ViewHand */
|
||||||
|
public ViewHand getPnlHand() {
|
||||||
|
return pnlHand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return JPanel */
|
||||||
|
public JPanel getPnlMessage() {
|
||||||
|
return pnlMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ViewInput */
|
||||||
|
public ViewInput getPnlInput() {
|
||||||
|
return pnlInput;
|
||||||
|
}
|
||||||
|
}
|
||||||
107
src/main/java/forge/view/match/ViewCardviewer.java
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
package forge.view.match;
|
||||||
|
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import forge.Card;
|
||||||
|
import forge.ImageCache;
|
||||||
|
import forge.control.match.ControlCardviewer;
|
||||||
|
import forge.gui.skin.FPanel;
|
||||||
|
import forge.view.toolbox.CardDetailPanel;
|
||||||
|
import forge.view.toolbox.FVerticalTabPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vertical tab panel for viewing card picture and/or details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ViewCardviewer {
|
||||||
|
private List<JPanel> panelList;
|
||||||
|
private ControlCardviewer control;
|
||||||
|
|
||||||
|
private CardPicPanel pnlCardPic;
|
||||||
|
private CardDetailPanel pnlCardDetail;
|
||||||
|
private FVerticalTabPanel vtpCardviewer;
|
||||||
|
|
||||||
|
private int w, h;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ViewCardviewer() {
|
||||||
|
// Assemble card pic viewer
|
||||||
|
panelList = new ArrayList<JPanel>();
|
||||||
|
|
||||||
|
pnlCardPic = new CardPicPanel();
|
||||||
|
pnlCardPic.setOpaque(false);
|
||||||
|
pnlCardPic.setName("Picture");
|
||||||
|
pnlCardPic.setToolTipText("Card Picture");
|
||||||
|
panelList.add(pnlCardPic);
|
||||||
|
|
||||||
|
pnlCardDetail = new CardDetailPanel();
|
||||||
|
pnlCardDetail.setOpaque(false);
|
||||||
|
pnlCardDetail.setName("Detail");
|
||||||
|
pnlCardDetail.setToolTipText("Card Text");
|
||||||
|
panelList.add(pnlCardDetail);
|
||||||
|
|
||||||
|
vtpCardviewer = new FVerticalTabPanel(panelList);
|
||||||
|
|
||||||
|
// After all components are in place, instantiate controller.
|
||||||
|
control = new ControlCardviewer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlCardviewer */
|
||||||
|
public ControlCardviewer getController() {
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card picture handling in side panel of match.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class CardPicPanel extends FPanel {
|
||||||
|
private Card card = null;
|
||||||
|
|
||||||
|
/** @param c   Card object */
|
||||||
|
public void setCard(Card c) {
|
||||||
|
this.card = c;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return Card */
|
||||||
|
public Card getCard() {
|
||||||
|
return this.card;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
|
||||||
|
if (card != null) {
|
||||||
|
w = getWidth();
|
||||||
|
h = (int) (w / 0.7);
|
||||||
|
BufferedImage img = ImageCache.getImage(card, w, h);
|
||||||
|
g.drawImage(img, 0, (int) ((getHeight() - h) / 2), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return CardPicPanel */
|
||||||
|
public CardPicPanel getPnlCardPic() {
|
||||||
|
return pnlCardPic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return CardDetailPanel */
|
||||||
|
public CardDetailPanel getPnlCardDetail() {
|
||||||
|
return pnlCardDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return FVerticalTabPanel */
|
||||||
|
public FVerticalTabPanel getVtpCardviewer() {
|
||||||
|
return vtpCardviewer;
|
||||||
|
}
|
||||||
|
}
|
||||||
388
src/main/java/forge/view/match/ViewDock.java
Normal file
@@ -0,0 +1,388 @@
|
|||||||
|
package forge.view.match;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.FocusAdapter;
|
||||||
|
import java.awt.event.FocusEvent;
|
||||||
|
import java.awt.event.KeyAdapter;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Singletons;
|
||||||
|
import forge.control.match.ControlDock;
|
||||||
|
import forge.gui.skin.FButton;
|
||||||
|
import forge.gui.skin.FPanel;
|
||||||
|
import forge.gui.skin.FRoundedPanel;
|
||||||
|
import forge.gui.skin.FSkin;
|
||||||
|
import forge.properties.ForgePreferences;
|
||||||
|
import forge.view.toolbox.FOverlay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swing component for button dock.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ViewDock extends FRoundedPanel {
|
||||||
|
private FSkin skin;
|
||||||
|
private ControlDock control;
|
||||||
|
private Map<String, KeyboardShortcutField> keyboardShortcutFields;
|
||||||
|
private Action actClose, actSaveKeyboardShortcuts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swing component for button dock.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ViewDock() {
|
||||||
|
super();
|
||||||
|
setCorners(new boolean[] {false, false, false, false});
|
||||||
|
setBorders(new boolean[] {true, true, false, true});
|
||||||
|
setToolTipText("Shortcut Button Dock");
|
||||||
|
setBackground(AllZone.getSkin().getClrTheme());
|
||||||
|
setLayout(new MigLayout("insets 0, gap 0, ay center, ax center"));
|
||||||
|
String constraints = "w 30px!, h 30px!, gap 0 10px";
|
||||||
|
skin = AllZone.getSkin();
|
||||||
|
keyboardShortcutFields = new HashMap<String, KeyboardShortcutField>();
|
||||||
|
|
||||||
|
actClose = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
AllZone.getOverlay().hideOverlay();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
actSaveKeyboardShortcuts = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
control.saveKeyboardShortcuts();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
JLabel btnConcede = new DockButton(skin.getIconConcede(), "Concede Game");
|
||||||
|
btnConcede.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
control.concede();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JLabel btnShortcuts = new DockButton(skin.getIconShortcuts(), "Keyboard Shortcuts");
|
||||||
|
btnShortcuts.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
overlayKeyboard();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JLabel btnSettings = new DockButton(skin.getIconSettings(), "Game Settings");
|
||||||
|
btnSettings.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
overlaySettings();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JLabel btnEndTurn = new DockButton(skin.getIconEndTurn(), "Game Settings");
|
||||||
|
btnEndTurn.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
control.endTurn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
add(btnConcede, constraints);
|
||||||
|
add(btnShortcuts, constraints);
|
||||||
|
add(btnSettings, constraints);
|
||||||
|
add(btnEndTurn, constraints);
|
||||||
|
|
||||||
|
// After all components are in place, instantiate controller.
|
||||||
|
control = new ControlDock(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlDock */
|
||||||
|
public ControlDock getController() {
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buttons in Dock. JLabels are used to allow hover effects.
|
||||||
|
*/
|
||||||
|
public class DockButton extends JLabel {
|
||||||
|
private Image img;
|
||||||
|
private Color hoverBG = skin.getClrHover();
|
||||||
|
private Color defaultBG = new Color(0, 0, 0, 0);
|
||||||
|
private Color clrBorders = new Color(0, 0, 0, 0);
|
||||||
|
private int w, h;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buttons in Dock. JLabels are used to allow hover effects.
|
||||||
|
*
|
||||||
|
* @param i0   ImageIcon to show in button
|
||||||
|
* @param s0   Tooltip string
|
||||||
|
*/
|
||||||
|
public DockButton(ImageIcon i0, String s0) {
|
||||||
|
super();
|
||||||
|
setToolTipText(s0);
|
||||||
|
setOpaque(false);
|
||||||
|
setBackground(defaultBG);
|
||||||
|
img = i0.getImage();
|
||||||
|
|
||||||
|
addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
clrBorders = skin.getClrBorders();
|
||||||
|
setBackground(hoverBG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
clrBorders = new Color(0, 0, 0, 0);
|
||||||
|
setBackground(defaultBG);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
w = getWidth();
|
||||||
|
h = getHeight();
|
||||||
|
g.setColor(getBackground());
|
||||||
|
g.fillRect(0, 0, w, h);
|
||||||
|
g.setColor(clrBorders);
|
||||||
|
g.drawRect(0, 0, w - 1, h - 1);
|
||||||
|
g.drawImage(img, 0, 0, w, h, null);
|
||||||
|
super.paintComponent(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
private void overlayKeyboard() {
|
||||||
|
FOverlay overlay = AllZone.getOverlay();
|
||||||
|
overlay.removeAll();
|
||||||
|
overlay.setLayout(new MigLayout("insets 0"));
|
||||||
|
overlay.showOverlay();
|
||||||
|
|
||||||
|
FPanel parent = new FPanel();
|
||||||
|
parent.setBGImg(skin.getTexture1());
|
||||||
|
parent.setBorder(new LineBorder(skin.getClrBorders(), 1));
|
||||||
|
parent.setLayout(new MigLayout("insets 0, wrap 2, ax center, ay center"));
|
||||||
|
overlay.add(parent, "w 80%!, h 80%!, gaptop 10%, gapleft 10%, span 2 1");
|
||||||
|
|
||||||
|
FButton btnOK = new FButton();
|
||||||
|
FButton btnCancel = new FButton();
|
||||||
|
|
||||||
|
overlay.add(btnOK, "width 30%, newline, gapright 10%, gapleft 15%, gaptop 10px");
|
||||||
|
overlay.add(btnCancel, "width 30%!");
|
||||||
|
|
||||||
|
btnOK.setAction(actSaveKeyboardShortcuts);
|
||||||
|
btnOK.setText("Save and Exit");
|
||||||
|
|
||||||
|
btnCancel.setAction(actClose);
|
||||||
|
btnCancel.setText("Exit Without Save");
|
||||||
|
|
||||||
|
KeyboardShortcutLabel lblBlurb = new KeyboardShortcutLabel();
|
||||||
|
lblBlurb.setText("<html><center>Focus in a box and press a key.<br>"
|
||||||
|
+ "Backspace will remove the last keypress.<br>"
|
||||||
|
+ "Restart Forge to map any new changes.</center></html>");
|
||||||
|
parent.add(lblBlurb, "span 2 1, gapbottom 30px");
|
||||||
|
|
||||||
|
ForgePreferences fp = Singletons.getModel().getPreferences();
|
||||||
|
|
||||||
|
// Keyboard shortcuts are a bit tricky to make, since they involve three
|
||||||
|
// different parts of the codebase: Preferences, main match control, and
|
||||||
|
// the customize button in the dock. To make a keyboard shortcut:
|
||||||
|
//
|
||||||
|
// 1. Go to ForgePreferences and set a variable, default value, setter, and getter
|
||||||
|
// 2. Go to ControlMatchUI and map an action using mapKeyboardShortcuts
|
||||||
|
// 3. (Optional) Come back to this file and add a new KeyboardShortcutField so
|
||||||
|
// the user can customize this shortcut. Update ControlDock to ensure any
|
||||||
|
// changes will be saved.
|
||||||
|
|
||||||
|
// Keyboard shortcuts must be created, then added to the HashMap to help saving.
|
||||||
|
// Their actions must also be declared, using mapKeyboardShortcuts in ControlMatchUI.
|
||||||
|
final KeyboardShortcutField showStack = new KeyboardShortcutField(fp.getShowStackShortcut());
|
||||||
|
this.keyboardShortcutFields.put("showstack", showStack);
|
||||||
|
|
||||||
|
final KeyboardShortcutField showCombat = new KeyboardShortcutField(fp.getShowCombatShortcut());
|
||||||
|
this.keyboardShortcutFields.put("showcombat", showCombat);
|
||||||
|
|
||||||
|
final KeyboardShortcutField showConsole = new KeyboardShortcutField(fp.getShowConsoleShortcut());
|
||||||
|
this.keyboardShortcutFields.put("showconsole", showConsole);
|
||||||
|
|
||||||
|
final KeyboardShortcutField showPlayers = new KeyboardShortcutField(fp.getShowPlayersShortcut());
|
||||||
|
this.keyboardShortcutFields.put("showplayers", showPlayers);
|
||||||
|
|
||||||
|
final KeyboardShortcutField showDev = new KeyboardShortcutField(fp.getShowDevShortcut());
|
||||||
|
this.keyboardShortcutFields.put("showdev", showDev);
|
||||||
|
|
||||||
|
final KeyboardShortcutField concedeGame = new KeyboardShortcutField(fp.getConcedeShortcut());
|
||||||
|
this.keyboardShortcutFields.put("concede", concedeGame);
|
||||||
|
|
||||||
|
final KeyboardShortcutField showPicture = new KeyboardShortcutField(fp.getShowPictureShortcut());
|
||||||
|
this.keyboardShortcutFields.put("showpicture", showPicture);
|
||||||
|
|
||||||
|
final KeyboardShortcutField showDetail = new KeyboardShortcutField(fp.getShowDetailShortcut());
|
||||||
|
this.keyboardShortcutFields.put("showdetail", showDetail);
|
||||||
|
|
||||||
|
//
|
||||||
|
parent.add(new KeyboardShortcutLabel("Show stack tab: "), "w 200px!");
|
||||||
|
parent.add(showStack, "w 100px!");
|
||||||
|
parent.add(new KeyboardShortcutLabel("Show combat tab: "), "w 200px!");
|
||||||
|
parent.add(showCombat, "w 100px!");
|
||||||
|
parent.add(new KeyboardShortcutLabel("Show console tab: "), "w 200px!");
|
||||||
|
parent.add(showConsole, "w 100px!");
|
||||||
|
parent.add(new KeyboardShortcutLabel("Show players tab: "), "w 200px!");
|
||||||
|
parent.add(showPlayers, "w 100px!");
|
||||||
|
parent.add(new KeyboardShortcutLabel("Show devmode tab: "), "w 200px!");
|
||||||
|
parent.add(showDev, "w 100px!");
|
||||||
|
parent.add(new KeyboardShortcutLabel("Concede game: "), "w 200px!");
|
||||||
|
parent.add(concedeGame, "w 100px!");
|
||||||
|
parent.add(new KeyboardShortcutLabel("Show card picture: "), "w 200px!");
|
||||||
|
parent.add(showPicture, "w 100px!");
|
||||||
|
parent.add(new KeyboardShortcutLabel("Show card detail: "), "w 200px!");
|
||||||
|
parent.add(showDetail, "w 100px!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
private void overlaySettings() {
|
||||||
|
FOverlay overlay = AllZone.getOverlay();
|
||||||
|
overlay.setLayout(new MigLayout("insets 0"));
|
||||||
|
overlay.showOverlay();
|
||||||
|
|
||||||
|
JPanel parent = new JPanel();
|
||||||
|
parent.setBackground(Color.red.darker());
|
||||||
|
overlay.add(parent, "w 80%!, h 80%!, gaptop 10%, gapleft 10%, span 2 1");
|
||||||
|
|
||||||
|
FButton btnOK = new FButton("Save and Exit");
|
||||||
|
FButton btnCancel = new FButton("Exit Without Save");
|
||||||
|
|
||||||
|
overlay.add(btnOK, "width 30%, newline, gapright 10%, gapleft 15%, gaptop 10px");
|
||||||
|
overlay.add(btnCancel, "width 30%!");
|
||||||
|
|
||||||
|
btnOK.setAction(actClose);
|
||||||
|
btnOK.setText("Save and Exit");
|
||||||
|
|
||||||
|
btnCancel.setAction(actClose);
|
||||||
|
btnCancel.setText("Exit Without Save");
|
||||||
|
|
||||||
|
JLabel test = new JLabel();
|
||||||
|
test.setForeground(Color.white);
|
||||||
|
test.setText("<html><center>'Settings' does not do anything yet.<br>"
|
||||||
|
+ "This button is just here to demonstrate the dock feature.<br>"
|
||||||
|
+ "'Settings' can be removed or developed further.</center></html>");
|
||||||
|
|
||||||
|
parent.add(test);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Small private class to centralize label styling. */
|
||||||
|
private class KeyboardShortcutLabel extends JLabel {
|
||||||
|
public KeyboardShortcutLabel() {
|
||||||
|
this("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardShortcutLabel(String s0) {
|
||||||
|
super(s0);
|
||||||
|
|
||||||
|
this.setForeground(skin.getClrText());
|
||||||
|
this.setFont(skin.getFont1().deriveFont(Font.PLAIN, 16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A JTextField plus a "codeString" property, that stores keycodes for the shortcut.
|
||||||
|
* Also, an action listener that handles translation of keycodes into characters and
|
||||||
|
* (dis)assembly of keycode stack.
|
||||||
|
*/
|
||||||
|
public class KeyboardShortcutField extends JTextField {
|
||||||
|
private String codeString;
|
||||||
|
|
||||||
|
/** A JTextField plus a "codeString" property, that stores keycodes for the shortcut.
|
||||||
|
* Also, an action listener that handles translation of keycodes into characters and
|
||||||
|
* (dis)assembly of keycode stack.
|
||||||
|
*
|
||||||
|
* This constructor sets the keycode string for this shortcut.
|
||||||
|
* Important: this parameter is keyCODEs not keyCHARs.
|
||||||
|
*
|
||||||
|
* @param s0   The string of keycodes for this shortcut
|
||||||
|
*/
|
||||||
|
public KeyboardShortcutField(String s0) {
|
||||||
|
this();
|
||||||
|
this.setCodeString(s0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A JTextField plus a "codeString" property, that stores keycodes for the shortcut.
|
||||||
|
* Also, an action listener that handles translation of keycodes into characters and
|
||||||
|
* (dis)assembly of keycode stack.
|
||||||
|
*/
|
||||||
|
public KeyboardShortcutField() {
|
||||||
|
super();
|
||||||
|
this.setEditable(false);
|
||||||
|
this.setFont(skin.getFont1().deriveFont(Font.PLAIN, 14));
|
||||||
|
|
||||||
|
this.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
control.addKeyCode(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addFocusListener(new FocusAdapter() {
|
||||||
|
@Override
|
||||||
|
public void focusGained(FocusEvent e) {
|
||||||
|
setBackground(skin.getClrActive());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void focusLost(FocusEvent e) {
|
||||||
|
setBackground(Color.white);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return String */
|
||||||
|
public String getCodeString() {
|
||||||
|
return codeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param s0   The new code string (space delimited) */
|
||||||
|
public void setCodeString(String s0) {
|
||||||
|
if (s0.equals("null")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
codeString = s0.trim();
|
||||||
|
|
||||||
|
List<String> codes = new ArrayList<String>(Arrays.asList(codeString.split(" ")));
|
||||||
|
List<String> displayText = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (String s : codes) {
|
||||||
|
if (!s.isEmpty()) {
|
||||||
|
displayText.add(KeyEvent.getKeyText(Integer.valueOf(s)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setText(StringUtils.join(displayText, ' '));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return Map<String, JTextField> */
|
||||||
|
public Map<String, KeyboardShortcutField> getKeyboardShortcutFields() {
|
||||||
|
return keyboardShortcutFields;
|
||||||
|
}
|
||||||
|
}
|
||||||
628
src/main/java/forge/view/match/ViewField.java
Normal file
@@ -0,0 +1,628 @@
|
|||||||
|
package forge.view.match;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.ScrollPaneConstants;
|
||||||
|
import javax.swing.border.Border;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
import javax.swing.border.MatteBorder;
|
||||||
|
|
||||||
|
import arcane.ui.PlayArea;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Player;
|
||||||
|
import forge.Constant.Zone;
|
||||||
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
|
import forge.control.match.ControlField;
|
||||||
|
import forge.gui.skin.FPanel;
|
||||||
|
import forge.gui.skin.FRoundedPanel;
|
||||||
|
import forge.gui.skin.FSkin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assembles Swing components of player field instance.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ViewField extends FRoundedPanel {
|
||||||
|
private FSkin skin;
|
||||||
|
private int counter;
|
||||||
|
|
||||||
|
private ControlField control;
|
||||||
|
private PlayArea tabletop;
|
||||||
|
|
||||||
|
private Border hoverBorder, inactiveBorder;
|
||||||
|
|
||||||
|
private DetailLabel
|
||||||
|
lblHand, lblGraveyard, lblLibrary,
|
||||||
|
lblExile, lblFlashback, lblPoison,
|
||||||
|
lblBlack, lblBlue, lblGreen,
|
||||||
|
lblRed, lblWhite, lblColorless;
|
||||||
|
|
||||||
|
private PhaseLabel
|
||||||
|
lblUpkeep, lblDraw, lblBeginCombat, lblEndCombat, lblEndTurn;
|
||||||
|
|
||||||
|
private JLabel lblLife;
|
||||||
|
private Map<String, JLabel> keywordLabels;
|
||||||
|
private Color transparent = new Color(0, 0, 0, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assembles Swing components of player field instance.
|
||||||
|
*
|
||||||
|
* @param player   a Player object.
|
||||||
|
*/
|
||||||
|
public ViewField(Player player) {
|
||||||
|
super();
|
||||||
|
setOpaque(false);
|
||||||
|
setLayout(new MigLayout("insets 1% 0.5%, gap 0.5%"));
|
||||||
|
setCornerRadius(5);
|
||||||
|
setToolTipText(player.getName() + " Gameboard");
|
||||||
|
setBackground(AllZone.getSkin().getClrTheme());
|
||||||
|
|
||||||
|
skin = AllZone.getSkin();
|
||||||
|
inactiveBorder = new LineBorder(new Color(0, 0, 0, 0), 1);
|
||||||
|
hoverBorder = new LineBorder(skin.getClrBorders(), 1);
|
||||||
|
counter = -1;
|
||||||
|
|
||||||
|
JScrollPane scroller = new JScrollPane();
|
||||||
|
tabletop = new PlayArea(scroller, true);
|
||||||
|
|
||||||
|
scroller.setViewportView(tabletop);
|
||||||
|
scroller.setOpaque(false);
|
||||||
|
scroller.getViewport().setOpaque(false);
|
||||||
|
scroller.setBorder(null);
|
||||||
|
tabletop.setBorder(new MatteBorder(0, 1, 0, 0, skin.getClrBorders()));
|
||||||
|
tabletop.setOpaque(false);
|
||||||
|
|
||||||
|
GridBagConstraints gbc = new GridBagConstraints();
|
||||||
|
gbc.fill = GridBagConstraints.BOTH;
|
||||||
|
|
||||||
|
//
|
||||||
|
Avatar pic = new Avatar("res/pics/icons/unknown.jpg");
|
||||||
|
Details pool = new Details();
|
||||||
|
|
||||||
|
add(pic, "h 98%!, w 10%!");
|
||||||
|
add(pool, "h 98%!, w 11%!");
|
||||||
|
add(scroller, "h 98%!, w 77%!");
|
||||||
|
|
||||||
|
// After all components are in place, instantiate controller.
|
||||||
|
control = new ControlField(player, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlField */
|
||||||
|
public ControlField getController() {
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handles observer update of player Zones - hand, graveyard, etc.
|
||||||
|
*
|
||||||
|
* @param p0   Player obj
|
||||||
|
*/
|
||||||
|
public void updateZones(Player p0) {
|
||||||
|
getLblHand().setText(""
|
||||||
|
+ p0.getZone(Zone.Hand).size());
|
||||||
|
getLblGraveyard().setText(""
|
||||||
|
+ p0.getZone(Zone.Graveyard).size());
|
||||||
|
getLblLibrary().setText(""
|
||||||
|
+ p0.getZone(Zone.Library).size());
|
||||||
|
getLblFlashback().setText(""
|
||||||
|
+ CardFactoryUtil.getExternalZoneActivationCards(p0).size());
|
||||||
|
getLblExile().setText(""
|
||||||
|
+ p0.getZone(Zone.Exile).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handles observer update of non-Zone details - life, poison, etc.
|
||||||
|
* Also updates "players" panel in tabber for this player.
|
||||||
|
*
|
||||||
|
* @param p0   Player obj
|
||||||
|
*/
|
||||||
|
public void updateDetails(Player p0) {
|
||||||
|
// "Players" panel update
|
||||||
|
ViewTopLevel t = (ViewTopLevel) AllZone.getDisplay();
|
||||||
|
t.getTabberController().getView().updatePlayerLabels(p0);
|
||||||
|
|
||||||
|
// Poison/life
|
||||||
|
getLblLife().setText("" + p0.getLife());
|
||||||
|
getLblPoison().setText("" + p0.getPoisonCounters());
|
||||||
|
|
||||||
|
// Hide all keyword labels, then show the appropriate ones.
|
||||||
|
for (JLabel lbl : keywordLabels.values()) {
|
||||||
|
lbl.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String s : p0.getKeywords()) {
|
||||||
|
keywordLabels.get(s).setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//========= Retrieval methods
|
||||||
|
/** @return PlayArea where cards for this field are in play */
|
||||||
|
public PlayArea getTabletop() {
|
||||||
|
return tabletop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel */
|
||||||
|
public JLabel getLblLife() {
|
||||||
|
return lblLife;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for hand cards */
|
||||||
|
public DetailLabel getLblHand() {
|
||||||
|
return lblHand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for library cards */
|
||||||
|
public DetailLabel getLblLibrary() {
|
||||||
|
return lblLibrary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for graveyard cards */
|
||||||
|
public DetailLabel getLblGraveyard() {
|
||||||
|
return lblGraveyard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for exiled cards */
|
||||||
|
public DetailLabel getLblExile() {
|
||||||
|
return lblExile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for flashback cards */
|
||||||
|
public DetailLabel getLblFlashback() {
|
||||||
|
return lblFlashback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for poison counters */
|
||||||
|
public DetailLabel getLblPoison() {
|
||||||
|
return lblPoison;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for colorless mana count */
|
||||||
|
public DetailLabel getLblColorless() {
|
||||||
|
return lblColorless;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for black mana count */
|
||||||
|
public DetailLabel getLblBlack() {
|
||||||
|
return lblBlack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for blue mana count */
|
||||||
|
public DetailLabel getLblBlue() {
|
||||||
|
return lblBlue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for green mana count */
|
||||||
|
public DetailLabel getLblGreen() {
|
||||||
|
return lblGreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for red mana count */
|
||||||
|
public DetailLabel getLblRed() {
|
||||||
|
return lblRed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DetailLabel for white mana count */
|
||||||
|
public DetailLabel getLblWhite() {
|
||||||
|
return lblWhite;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phases
|
||||||
|
/** @return PhaseLabel for upkeep */
|
||||||
|
public PhaseLabel getLblUpkeep() {
|
||||||
|
return lblUpkeep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return PhaseLabel for draw */
|
||||||
|
public PhaseLabel getLblDraw() {
|
||||||
|
return lblDraw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return PhaseLabel for beginning of combat*/
|
||||||
|
public PhaseLabel getLblBeginCombat() {
|
||||||
|
return lblBeginCombat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return PhaseLabel for end of combat */
|
||||||
|
public PhaseLabel getLblEndCombat() {
|
||||||
|
return lblEndCombat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return PhaseLabel for end of turn */
|
||||||
|
public PhaseLabel getLblEndTurn() {
|
||||||
|
return lblEndTurn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return Map<String,JLabel> */
|
||||||
|
public Map<String, JLabel> getKeywordLabels() {
|
||||||
|
return keywordLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
//========== Custom classes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows user icon, keywords, and phase for this field.
|
||||||
|
*/
|
||||||
|
private class Avatar extends FPanel {
|
||||||
|
private ImageIcon icon;
|
||||||
|
private Color transparent = new Color(0, 0, 0, 0);
|
||||||
|
|
||||||
|
public Avatar(String filename) {
|
||||||
|
// Panel and background image icon init
|
||||||
|
super();
|
||||||
|
setOpaque(false);
|
||||||
|
setLayout(new MigLayout("fill, wrap, insets 0, gap 0"));
|
||||||
|
icon = new ImageIcon(filename);
|
||||||
|
|
||||||
|
// Life label
|
||||||
|
lblLife = new JLabel("--");
|
||||||
|
lblLife.setBorder(inactiveBorder);
|
||||||
|
lblLife.setToolTipText("<html>Player life.<br>Click to select player.</html>");
|
||||||
|
lblLife.setFont(skin.getFont1().deriveFont(Font.BOLD, 18));
|
||||||
|
lblLife.setForeground(skin.getClrText());
|
||||||
|
lblLife.setBackground(skin.getClrTheme().darker());
|
||||||
|
lblLife.setOpaque(true);
|
||||||
|
lblLife.setHorizontalAlignment(JLabel.CENTER);
|
||||||
|
lblLife.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
|
lblLife.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
lblLife.setBackground(AllZone.getSkin().getClrHover());
|
||||||
|
lblLife.setBorder(hoverBorder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
lblLife.setBackground(skin.getClrTheme());
|
||||||
|
lblLife.setBorder(inactiveBorder);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
add(lblLife, "w 100%!, dock north");
|
||||||
|
|
||||||
|
keywordLabels = new HashMap<String, JLabel>();
|
||||||
|
// TODO link these map keys to correct keyword constant
|
||||||
|
keywordLabels.put("shroud", new KeywordLabel("Shroud"));
|
||||||
|
keywordLabels.put("extraturn", new KeywordLabel("+1 turn"));
|
||||||
|
keywordLabels.put("skipturn", new KeywordLabel("Skip turn"));
|
||||||
|
keywordLabels.put("problack", new KeywordLabel("Pro: Black"));
|
||||||
|
keywordLabels.put("problue", new KeywordLabel("Pro: Blue"));
|
||||||
|
keywordLabels.put("progreen", new KeywordLabel("Pro: Green"));
|
||||||
|
keywordLabels.put("prored", new KeywordLabel("Pro: Red"));
|
||||||
|
keywordLabels.put("prowhite", new KeywordLabel("Pro: White"));
|
||||||
|
|
||||||
|
JPanel pnlKeywords = new JPanel(new MigLayout("insets 0, wrap, hidemode 2"));
|
||||||
|
pnlKeywords.setOpaque(false);
|
||||||
|
for (JLabel lbl : keywordLabels.values()) {
|
||||||
|
pnlKeywords.add(lbl);
|
||||||
|
}
|
||||||
|
|
||||||
|
JScrollPane scrKeywords = new JScrollPane(pnlKeywords,
|
||||||
|
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||||
|
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
|
|
||||||
|
scrKeywords.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||||
|
scrKeywords.setOpaque(false);
|
||||||
|
scrKeywords.getViewport().setOpaque(false);
|
||||||
|
scrKeywords.setViewportView(pnlKeywords);
|
||||||
|
add(scrKeywords, "w 100%!, growy");
|
||||||
|
|
||||||
|
JPanel phase = new JPanel();
|
||||||
|
phase.setOpaque(false);
|
||||||
|
phase.setLayout(new MigLayout("fillx, insets 0, gap 0"));
|
||||||
|
add(phase, "w 100%!, h 20px!");
|
||||||
|
|
||||||
|
// Constraints string must be set once, for ease and also
|
||||||
|
// since dynamic sizing is buggy.
|
||||||
|
String constraints = "w 20%!, h 100%!";
|
||||||
|
|
||||||
|
lblUpkeep = new PhaseLabel("UP");
|
||||||
|
lblUpkeep.setToolTipText("<html>Phase: Upkeep<br>Click to toggle.</html>");
|
||||||
|
phase.add(lblUpkeep, constraints);
|
||||||
|
|
||||||
|
lblDraw = new PhaseLabel("DR");
|
||||||
|
lblDraw.setToolTipText("<html>Phase: Draw<br>Click to toggle.</html>");
|
||||||
|
phase.add(lblDraw, constraints);
|
||||||
|
|
||||||
|
lblBeginCombat = new PhaseLabel("BC");
|
||||||
|
lblBeginCombat.setToolTipText("<html>Phase: Begin Combat<br>Click to toggle.</html>");
|
||||||
|
phase.add(lblBeginCombat, constraints);
|
||||||
|
|
||||||
|
lblEndCombat = new PhaseLabel("EC");
|
||||||
|
lblEndCombat.setToolTipText("<html>Phase: End Combat<br>Click to toggle.</html>");
|
||||||
|
phase.add(lblEndCombat, constraints);
|
||||||
|
|
||||||
|
lblEndTurn = new PhaseLabel("ET");
|
||||||
|
lblEndTurn.setToolTipText("<html>Phase: End Turn<br>Click to toggle.</html>");
|
||||||
|
phase.add(lblEndTurn, constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
setBorder(new MatteBorder(getWidth(), 0, 0, 0, transparent));
|
||||||
|
g.drawImage(icon.getImage(), 0, 0, getWidth(), getWidth(),
|
||||||
|
0, 0, icon.getIconWidth(), icon.getIconHeight(), null);
|
||||||
|
lblLife.setFont(skin.getFont1().deriveFont(Font.PLAIN, (int) (getWidth() / 4)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The "details" section of player info:
|
||||||
|
* Hand, library, graveyard, exiled, flashback, poison,
|
||||||
|
* and mana pool (BBGRW and colorless).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// Design note: Labels are used here since buttons have various
|
||||||
|
// difficulties in displaying the desired "flat" background and
|
||||||
|
// also strange icon/action behavior.
|
||||||
|
private class Details extends JPanel {
|
||||||
|
public Details() {
|
||||||
|
super();
|
||||||
|
setLayout(new MigLayout("insets 0, gap 0, wrap 2, filly"));
|
||||||
|
setOpaque(false);
|
||||||
|
final String constraints = "w 50%!, h 12.5%!, growy";
|
||||||
|
|
||||||
|
// Hand, library, graveyard, exile, flashback, poison labels
|
||||||
|
lblGraveyard = new DetailLabel(new ImageIcon("res/images/symbols-13/detail_grave.png"), "99");
|
||||||
|
lblGraveyard.setToolTipText("Cards in graveyard");
|
||||||
|
add(lblGraveyard, constraints);
|
||||||
|
|
||||||
|
lblLibrary = new DetailLabel(new ImageIcon("res/images/symbols-13/detail_library.png"), "99");
|
||||||
|
lblLibrary.setToolTipText("Cards in library");
|
||||||
|
add(lblLibrary, constraints);
|
||||||
|
|
||||||
|
lblExile = new DetailLabel(new ImageIcon("res/images/symbols-13/detail_exile.png"), "99");
|
||||||
|
lblExile.setToolTipText("Exiled cards");
|
||||||
|
add(lblExile, constraints);
|
||||||
|
|
||||||
|
lblFlashback = new DetailLabel(new ImageIcon("res/images/symbols-13/detail_flashback.png"), "99");
|
||||||
|
lblFlashback.setToolTipText("Flashback cards");
|
||||||
|
add(lblFlashback, constraints);
|
||||||
|
|
||||||
|
lblHand = new DetailLabel(new ImageIcon("res/images/symbols-13/detail_hand.png"), "99");
|
||||||
|
lblHand.setToolTipText("Cards in hand");
|
||||||
|
add(lblHand, constraints);
|
||||||
|
|
||||||
|
lblPoison = new DetailLabel(new ImageIcon("res/images/symbols-13/detail_poison.png"), "99");
|
||||||
|
lblPoison.setToolTipText("Poison counters");
|
||||||
|
add(lblPoison, constraints);
|
||||||
|
|
||||||
|
// Black, Blue, Colorless, Green, Red, White mana labels
|
||||||
|
lblBlack = new DetailLabel(new ImageIcon("res/images/symbols-13/B.png"), "99");
|
||||||
|
lblBlack.setToolTipText("Black mana");
|
||||||
|
add(lblBlack, constraints);
|
||||||
|
|
||||||
|
lblBlue = new DetailLabel(new ImageIcon("res/images/symbols-13/U.png"), "99");
|
||||||
|
lblBlue.setToolTipText("Blue mana");
|
||||||
|
add(lblBlue, constraints);
|
||||||
|
|
||||||
|
lblGreen = new DetailLabel(new ImageIcon("res/images/symbols-13/G.png"), "99");
|
||||||
|
lblGreen.setToolTipText("Green mana");
|
||||||
|
add(lblGreen, constraints);
|
||||||
|
|
||||||
|
lblRed = new DetailLabel(new ImageIcon("res/images/symbols-13/R.png"), "99");
|
||||||
|
lblRed.setToolTipText("Red mana");
|
||||||
|
add(lblRed, constraints);
|
||||||
|
|
||||||
|
lblWhite = new DetailLabel(new ImageIcon("res/images/symbols-13/W.png"), "99");
|
||||||
|
lblWhite.setToolTipText("White mana");
|
||||||
|
add(lblWhite, constraints);
|
||||||
|
|
||||||
|
lblColorless = new DetailLabel(new ImageIcon("res/images/symbols-13/X.png"), "99");
|
||||||
|
lblColorless.setToolTipText("Colorless mana");
|
||||||
|
add(lblColorless, constraints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to show various values in "details" panel. Also increments
|
||||||
|
* grid bag constraints object as it goes, and zebra-stripes the labels.
|
||||||
|
*/
|
||||||
|
public class DetailLabel extends JLabel {
|
||||||
|
private final Dimension labelSize = new Dimension(40, 25);
|
||||||
|
private Color defaultBG;
|
||||||
|
private Color hoverBG;
|
||||||
|
private Color clrBorders;
|
||||||
|
private MouseAdapter madHover;
|
||||||
|
private int w, h;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of JLabel detailing info about field:
|
||||||
|
* has icon and optional hover effect.
|
||||||
|
*
|
||||||
|
* @param icon   Label's icon
|
||||||
|
* @param txt   Label's text
|
||||||
|
*/
|
||||||
|
public DetailLabel(ImageIcon icon, String txt) {
|
||||||
|
super();
|
||||||
|
setIcon(icon);
|
||||||
|
setText(txt);
|
||||||
|
setOpaque(false);
|
||||||
|
setForeground(skin.getClrText());
|
||||||
|
setPreferredSize(labelSize);
|
||||||
|
setMaximumSize(labelSize);
|
||||||
|
setMinimumSize(labelSize);
|
||||||
|
setBorder(new LineBorder(new Color(0, 0, 0, 0), 1));
|
||||||
|
setHorizontalAlignment(CENTER);
|
||||||
|
|
||||||
|
// Increment counter and check for zebra. Set default BG
|
||||||
|
// so hover effects return to the same color.
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
if (counter % 4 == 2 || counter % 4 == 3) {
|
||||||
|
defaultBG = skin.getClrZebra();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
defaultBG = skin.getClrTheme();
|
||||||
|
}
|
||||||
|
setBackground(defaultBG);
|
||||||
|
|
||||||
|
madHover = new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
setBackground(hoverBG);
|
||||||
|
clrBorders = skin.getClrBorders();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
setBackground(defaultBG);
|
||||||
|
clrBorders = transparent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
hoverBG = skin.getClrHover();
|
||||||
|
clrBorders = transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Enable hover effects for this label. */
|
||||||
|
public void enableHover() {
|
||||||
|
addMouseListener(madHover);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Disable hover effects for this label. */
|
||||||
|
public void disableHover() {
|
||||||
|
removeMouseListener(madHover);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
w = getWidth();
|
||||||
|
h = getHeight();
|
||||||
|
g.setColor(getBackground());
|
||||||
|
g.fillRect(0, 0, w, h);
|
||||||
|
g.setColor(clrBorders);
|
||||||
|
g.drawRect(0, 0, w - 1, h - 1);
|
||||||
|
this.setFont(skin.getFont1().deriveFont(Font.PLAIN, (int) (h / 2)));
|
||||||
|
super.paintComponent(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class KeywordLabel extends JLabel {
|
||||||
|
public KeywordLabel(String s) {
|
||||||
|
super(s);
|
||||||
|
setToolTipText(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows phase labels, handles repainting and on/off states. A PhaseLabel
|
||||||
|
* has "skip" and "active" states, meaning "this phase is (not) skipped"
|
||||||
|
* and "this is the current phase".
|
||||||
|
*/
|
||||||
|
public class PhaseLabel extends JLabel {
|
||||||
|
private boolean enabled = true;
|
||||||
|
private boolean active = false;
|
||||||
|
private boolean hover = false;
|
||||||
|
private Color hoverBG = AllZone.getSkin().getClrHover();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows phase labels, handles repainting and on/off states. A PhaseLabel
|
||||||
|
* has "skip" and "active" states, meaning "this phase is (not) skipped"
|
||||||
|
* and "this is the current phase".
|
||||||
|
*
|
||||||
|
* @param txt   Label text
|
||||||
|
*/
|
||||||
|
public PhaseLabel(String txt) {
|
||||||
|
super(txt);
|
||||||
|
this.setHorizontalTextPosition(CENTER);
|
||||||
|
this.setHorizontalAlignment(CENTER);
|
||||||
|
|
||||||
|
addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if (enabled) { enabled = false; }
|
||||||
|
else { enabled = true; }
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
hover = true;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
hover = false;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether play pauses at this phase or not.
|
||||||
|
*
|
||||||
|
* @param b   boolean, true if play pauses
|
||||||
|
*/
|
||||||
|
public void setEnabled(boolean b) {
|
||||||
|
enabled = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether play pauses at this phase or not.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean getEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this phase is the current phase (or not).
|
||||||
|
*
|
||||||
|
* @param b   boolean, true if phase is current
|
||||||
|
*/
|
||||||
|
public void setActive(boolean b) {
|
||||||
|
active = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this phase is the current phase (or not).
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean getActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
int w = getWidth();
|
||||||
|
int h = getHeight();
|
||||||
|
Color c;
|
||||||
|
|
||||||
|
// Set color according to skip or active or hover state of label
|
||||||
|
if (hover) {
|
||||||
|
c = hoverBG;
|
||||||
|
}
|
||||||
|
else if (enabled) {
|
||||||
|
c = Color.green;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c = Color.red;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active && !hover) {
|
||||||
|
c = c.darker().darker();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center vertically and horizontally. Show border if active.
|
||||||
|
g.setColor(c);
|
||||||
|
g.fillRoundRect(1, 1, w - 2, h - 2, 5, 5);
|
||||||
|
|
||||||
|
setFont(new Font("TAHOMA", Font.PLAIN, (int) (w / 2)));
|
||||||
|
g.setColor(Color.black);
|
||||||
|
super.paintComponent(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
171
src/main/java/forge/view/match/ViewHand.java
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
package forge.view.match;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.ScrollPaneConstants;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Card;
|
||||||
|
import forge.GuiDisplayUtil;
|
||||||
|
import forge.ImageCache;
|
||||||
|
import forge.control.match.ControlHand;
|
||||||
|
|
||||||
|
import forge.gui.skin.FRoundedPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIEW - Swing components for user hand.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ViewHand extends JScrollPane {
|
||||||
|
private FRoundedPanel pnlContent;
|
||||||
|
private ControlHand control;
|
||||||
|
private List<CardPanel> cardPanels = new ArrayList<CardPanel>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIEW - Swing components for user hand.
|
||||||
|
*/
|
||||||
|
public ViewHand() {
|
||||||
|
super(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
|
||||||
|
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
|
||||||
|
|
||||||
|
setOpaque(false);
|
||||||
|
getViewport().setOpaque(false);
|
||||||
|
getHorizontalScrollBar().setUnitIncrement(16);
|
||||||
|
setBorder(null);
|
||||||
|
|
||||||
|
// After all components are in place, instantiate controller.
|
||||||
|
control = new ControlHand(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlHand */
|
||||||
|
public ControlHand getController() {
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebuilds layout of the hand panel. Card panels are removed,
|
||||||
|
* the height and card aspect ratio are used to set layout column width,
|
||||||
|
* then card panels are added to the fresh layout.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// This design choice was made to allow the functionality of a JPanel
|
||||||
|
// while maintaining a scale-able view. Overridden paint methods could
|
||||||
|
// do this, but require heavy coding.
|
||||||
|
public void refreshLayout() {
|
||||||
|
// Remove all panels and recalculate layout scaling based on aspect ratio.
|
||||||
|
pnlContent = new FRoundedPanel();
|
||||||
|
pnlContent.setBackground(AllZone.getSkin().getClrTheme());
|
||||||
|
pnlContent.setCorners(new boolean[] {true, false, false, true});
|
||||||
|
pnlContent.setLayout(new MigLayout("insets 3 10 3 10"));
|
||||||
|
pnlContent.setSize(getViewport().getSize());
|
||||||
|
pnlContent.validate();
|
||||||
|
this.setViewportView(pnlContent);
|
||||||
|
|
||||||
|
int h = getViewport().getHeight() - 6;
|
||||||
|
pnlContent.setLayout(new MigLayout("align center"));
|
||||||
|
|
||||||
|
// Re-insert panel instances. Possible memory management problem
|
||||||
|
// from re-adding pre-existing panels. Doublestrike 22-11-11
|
||||||
|
cardPanels = new ArrayList<CardPanel>();
|
||||||
|
for (Card c : control.getCards()) {
|
||||||
|
CardPanel temp = new CardPanel(c);
|
||||||
|
cardPanels.add(temp);
|
||||||
|
pnlContent.add(temp, "h " + h + "px!, w " + (int) (h * 0.7) + "px!");
|
||||||
|
control.addCardPanelListeners(temp);
|
||||||
|
}
|
||||||
|
// Notify system of change.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CardPanel extends JPanel {
|
||||||
|
private static final long serialVersionUID = 509877513760665415L;
|
||||||
|
private Card card = null;
|
||||||
|
private Image img;
|
||||||
|
private int w, h = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Constructor for CardPanel.</p>
|
||||||
|
*
|
||||||
|
* @param c   Card object.
|
||||||
|
*/
|
||||||
|
public CardPanel(Card c) {
|
||||||
|
super();
|
||||||
|
this.card = c;
|
||||||
|
this.img = ImageCache.getImage(card);
|
||||||
|
|
||||||
|
setToolTipText("<html>" + c.getName() + "<br>" + GuiDisplayUtil.formatCardType(c) + "</html>");
|
||||||
|
|
||||||
|
// No image?
|
||||||
|
if (img == null) {
|
||||||
|
setBorder(new LineBorder(new Color(240, 240, 240), 1));
|
||||||
|
setLayout(new MigLayout("wrap, insets 2, gap 0"));
|
||||||
|
setOpaque(true);
|
||||||
|
setBackground(new Color(200, 200, 200));
|
||||||
|
|
||||||
|
JLabel lblManaCost = new JLabel(c.getManaCost());
|
||||||
|
lblManaCost.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||||
|
|
||||||
|
JLabel lblCardName = new JLabel(c.getName());
|
||||||
|
lblCardName.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
|
||||||
|
JLabel lblPowerToughness = new JLabel("");
|
||||||
|
lblPowerToughness.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||||
|
|
||||||
|
if (c.isFaceDown()) {
|
||||||
|
lblCardName.setText("Morph");
|
||||||
|
lblManaCost.setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.isCreature()) {
|
||||||
|
lblPowerToughness.setText(c.getNetAttack() + " / " + c.getNetDefense());
|
||||||
|
}
|
||||||
|
|
||||||
|
add(lblManaCost, "w 90%!");
|
||||||
|
add(lblCardName, "w 90%!");
|
||||||
|
add(lblPowerToughness, "w 90%!, gaptop 25");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setBorder(new LineBorder(Color.black, 1));
|
||||||
|
w = img.getWidth(null);
|
||||||
|
h = img.getHeight(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return Card */
|
||||||
|
public Card getCard() {
|
||||||
|
return this.card;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
if (img != null) {
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
g2d.drawImage(img, 0, 0, getWidth(), getHeight(), 0, 0, w, h, null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g.setColor(new Color(200, 200, 200));
|
||||||
|
g.drawRect(1, 1, getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return List<CardPanel> */
|
||||||
|
public List<CardPanel> getCardPanels() {
|
||||||
|
return cardPanels;
|
||||||
|
}
|
||||||
|
}
|
||||||
79
src/main/java/forge/view/match/ViewInput.java
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
package forge.view.match;
|
||||||
|
|
||||||
|
import java.awt.Font;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.control.match.ControlInput;
|
||||||
|
import forge.gui.skin.FButton;
|
||||||
|
import forge.gui.skin.FRoundedPanel;
|
||||||
|
import forge.gui.skin.FSkin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assembles Swing components of input area.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ViewInput extends FRoundedPanel {
|
||||||
|
private ControlInput control;
|
||||||
|
private JButton btnOK, btnCancel;
|
||||||
|
private JTextArea tarMessage;
|
||||||
|
private FSkin skin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assembles UI for input area (buttons and message panel).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ViewInput() {
|
||||||
|
super();
|
||||||
|
skin = AllZone.getSkin();
|
||||||
|
setToolTipText("Input Area");
|
||||||
|
setBackground(skin.getClrTheme());
|
||||||
|
setForeground(skin.getClrText());
|
||||||
|
setCorners(new boolean[] {false, false, false, true});
|
||||||
|
setBorders(new boolean[] {true, false, false, true});
|
||||||
|
|
||||||
|
setLayout(new MigLayout("wrap 2, fill, insets 0, gap 0"));
|
||||||
|
|
||||||
|
// Cancel button
|
||||||
|
btnCancel = new FButton("Cancel");
|
||||||
|
btnOK = new FButton("OK");
|
||||||
|
|
||||||
|
tarMessage = new JTextArea();
|
||||||
|
tarMessage.setOpaque(false);
|
||||||
|
tarMessage.setFocusable(false);
|
||||||
|
tarMessage.setEditable(false);
|
||||||
|
tarMessage.setLineWrap(true);
|
||||||
|
tarMessage.setForeground(skin.getClrText());
|
||||||
|
tarMessage.setFont(skin.getFont1().deriveFont(Font.PLAIN, 12));
|
||||||
|
add(tarMessage, "span 2 1, h 80%!, w 96%!, gapleft 2%, gaptop 1%");
|
||||||
|
add(btnOK, "w 47%!, gapright 2%, gapleft 1%");
|
||||||
|
add(btnCancel, "w 47%!, gapright 1%");
|
||||||
|
|
||||||
|
// After all components are in place, instantiate controller.
|
||||||
|
control = new ControlInput(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlInput */
|
||||||
|
public ControlInput getController() {
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return JButton */
|
||||||
|
public JButton getBtnOK() {
|
||||||
|
return btnOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return JButton */
|
||||||
|
public JButton getBtnCancel() {
|
||||||
|
return btnCancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return JTextArea */
|
||||||
|
public JTextArea getTarMessage() {
|
||||||
|
return tarMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
501
src/main/java/forge/view/match/ViewTabber.java
Normal file
@@ -0,0 +1,501 @@
|
|||||||
|
package forge.view.match;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.ScrollPaneConstants;
|
||||||
|
import javax.swing.border.Border;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.border.MatteBorder;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Constant;
|
||||||
|
import forge.MagicStack;
|
||||||
|
import forge.Player;
|
||||||
|
import forge.card.spellability.SpellAbilityStackInstance;
|
||||||
|
import forge.control.match.ControlTabber;
|
||||||
|
import forge.gui.MultiLineLabelUI;
|
||||||
|
import forge.gui.skin.FPanel;
|
||||||
|
import forge.gui.skin.FSkin;
|
||||||
|
import forge.view.toolbox.FVerticalTabPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vertical tab panel for viewing stack, combat, etc.
|
||||||
|
* Unfortunately, cannot extend a Swing component, since
|
||||||
|
* vertical tabs are generated dynamically in the constructor.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ViewTabber {
|
||||||
|
private List<JPanel> panelList;
|
||||||
|
private HashMap<Player, JLabel[]> detailLabels;
|
||||||
|
|
||||||
|
private ControlTabber control;
|
||||||
|
private FSkin skin;
|
||||||
|
|
||||||
|
private FPanel pnlStack, pnlCombat, pnlConsole, pnlPlayers, pnlDev;
|
||||||
|
|
||||||
|
private DevLabel lblMilling, lblHandView, lblLibraryView, lblGenerateMana,
|
||||||
|
lblSetupGame, lblTutor, lblCounterPermanent, lblTapPermanent, lblUntapPermanent,
|
||||||
|
lblUnlimitedLands, lblHumanLife;
|
||||||
|
|
||||||
|
private FVerticalTabPanel vtpTabber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assembles Swing components for tabber area in sidebar.
|
||||||
|
*/
|
||||||
|
public ViewTabber() {
|
||||||
|
skin = AllZone.getSkin();
|
||||||
|
|
||||||
|
// Assemble card pic viewer
|
||||||
|
panelList = new ArrayList<JPanel>();
|
||||||
|
String constraints = "wrap, insets 0, gap 0";
|
||||||
|
|
||||||
|
pnlStack = new FPanel();
|
||||||
|
pnlStack.setName("Stack");
|
||||||
|
pnlStack.setOpaque(false);
|
||||||
|
pnlStack.setLayout(new MigLayout(constraints));
|
||||||
|
pnlStack.setToolTipText("View Stack");
|
||||||
|
panelList.add(pnlStack);
|
||||||
|
|
||||||
|
pnlCombat = new FPanel();
|
||||||
|
pnlCombat.setName("Combat");
|
||||||
|
pnlCombat.setOpaque(false);
|
||||||
|
pnlCombat.setLayout(new MigLayout(constraints));
|
||||||
|
pnlCombat.setToolTipText("View Combat");
|
||||||
|
panelList.add(pnlCombat);
|
||||||
|
|
||||||
|
pnlConsole = new FPanel();
|
||||||
|
pnlConsole.setName("Log");
|
||||||
|
pnlConsole.setOpaque(false);
|
||||||
|
pnlConsole.setLayout(new MigLayout(constraints));
|
||||||
|
pnlConsole.setToolTipText("View Console");
|
||||||
|
panelList.add(pnlConsole);
|
||||||
|
|
||||||
|
pnlPlayers = new FPanel();
|
||||||
|
pnlPlayers.setName("Players");
|
||||||
|
pnlPlayers.setOpaque(false);
|
||||||
|
pnlPlayers.setLayout(new MigLayout(constraints));
|
||||||
|
pnlPlayers.setToolTipText("Player List");
|
||||||
|
panelList.add(pnlPlayers);
|
||||||
|
|
||||||
|
pnlDev = new FPanel();
|
||||||
|
pnlDev.setName("Dev");
|
||||||
|
pnlDev.setOpaque(false);
|
||||||
|
pnlDev.setLayout(new MigLayout(constraints));
|
||||||
|
pnlDev.setToolTipText("Developer Mode");
|
||||||
|
|
||||||
|
if (Constant.Runtime.DEV_MODE[0]) {
|
||||||
|
panelList.add(pnlDev);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate the various panels in the tabber.
|
||||||
|
populatePnlDev();
|
||||||
|
populatePnlPlayers();
|
||||||
|
populatePnlConsole();
|
||||||
|
|
||||||
|
vtpTabber = new FVerticalTabPanel(panelList);
|
||||||
|
vtpTabber.getContentPanel().setBorder(new MatteBorder(1, 0, 0, 1, skin.getClrBorders()));
|
||||||
|
|
||||||
|
// After all components are in place, instantiate controller.
|
||||||
|
control = new ControlTabber(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlTabber */
|
||||||
|
public ControlTabber getController() {
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes and adds JTextAreas to stack panel, which briefly summarize the
|
||||||
|
* spell and allow mouseover.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void updateStack() {
|
||||||
|
final MagicStack stack = AllZone.getStack();
|
||||||
|
final ViewTopLevel t = (ViewTopLevel) AllZone.getDisplay();
|
||||||
|
|
||||||
|
int count = 1;
|
||||||
|
JTextArea tar;
|
||||||
|
String txt, isOptional;
|
||||||
|
|
||||||
|
pnlStack.removeAll();
|
||||||
|
vtpTabber.showTab(0);
|
||||||
|
Font font = skin.getFont1().deriveFont(Font.PLAIN, 11);
|
||||||
|
Border border = new MatteBorder(0, 0, 1, 0, Color.black);
|
||||||
|
|
||||||
|
for (int i = stack.size() - 1; 0 <= i; i--) {
|
||||||
|
isOptional = stack.peekAbility(i).isOptionalTrigger() && stack.peekAbility(i).getSourceCard().getController().isHuman() ? "(OPTIONAL) " : "";
|
||||||
|
txt = (count++) + ". " + isOptional + stack.peekInstance(i).getStackDescription();
|
||||||
|
tar = new JTextArea(txt);
|
||||||
|
tar.setToolTipText(txt);
|
||||||
|
tar.setOpaque(false);
|
||||||
|
tar.setBorder(border);
|
||||||
|
tar.setFont(font);
|
||||||
|
tar.setFocusable(false);
|
||||||
|
tar.setEditable(false);
|
||||||
|
tar.setLineWrap(true);
|
||||||
|
tar.setWrapStyleWord(true);
|
||||||
|
|
||||||
|
final SpellAbilityStackInstance spell = stack.peekInstance(i);
|
||||||
|
|
||||||
|
tar.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
t.getCardviewerController().showCard(spell.getSpellAbility().getSourceCard());
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pnlStack.add(tar, "w 100%!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes and adds JTextAreas to combat panel, which briefly summarize the
|
||||||
|
* current combat situation.
|
||||||
|
*
|
||||||
|
* @param s   String message
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Note: Can (should?) be easily retrofitted to fit stack-style reporting:
|
||||||
|
// multiple text areas, with mouseovers highlighting combat cards. Doublestrike 06-11-11
|
||||||
|
public void updateCombat(String s) {
|
||||||
|
pnlCombat.removeAll();
|
||||||
|
vtpTabber.showTab(1);
|
||||||
|
|
||||||
|
Font font = skin.getFont1().deriveFont(Font.PLAIN, 11);
|
||||||
|
Border border = new MatteBorder(1, 0, 0, 0, Color.black);
|
||||||
|
|
||||||
|
JTextArea tar = new JTextArea(s);
|
||||||
|
tar.setOpaque(false);
|
||||||
|
tar.setBorder(border);
|
||||||
|
tar.setFont(font);
|
||||||
|
tar.setFocusable(false);
|
||||||
|
tar.setLineWrap(true);
|
||||||
|
pnlCombat.add(tar, "h 100%!, w 100%!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Updates labels in the "player" panel, which display non-critical details about
|
||||||
|
* each player in the game.
|
||||||
|
*
|
||||||
|
* @param p0   Player obj
|
||||||
|
*/
|
||||||
|
public void updatePlayerLabels(Player p0) {
|
||||||
|
JLabel[] temp = detailLabels.get(p0);
|
||||||
|
temp[0].setText("Life: " + String.valueOf(p0.getLife()));
|
||||||
|
temp[1].setText("Max hand: " + String.valueOf(p0.getMaxHandSize()));
|
||||||
|
temp[2].setText("Draw per turn: " + String.valueOf(p0.getNumDrawnThisTurn()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return FVerticalTabPanel */
|
||||||
|
public FVerticalTabPanel getVtpTabber() {
|
||||||
|
return vtpTabber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return FPanel */
|
||||||
|
public FPanel getPnlStack() {
|
||||||
|
return pnlStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return FPanel */
|
||||||
|
public FPanel getPnlCombat() {
|
||||||
|
return pnlCombat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return FPanel */
|
||||||
|
public FPanel getPnlPlayers() {
|
||||||
|
return pnlPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return FPanel */
|
||||||
|
public FPanel getPnlDev() {
|
||||||
|
return pnlDev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblMilling() {
|
||||||
|
return lblMilling;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblHandView() {
|
||||||
|
return lblHandView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblLibraryView() {
|
||||||
|
return lblLibraryView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblGenerateMana() {
|
||||||
|
return lblGenerateMana;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblSetupGame() {
|
||||||
|
return lblSetupGame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblTutor() {
|
||||||
|
return lblTutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblCounterPermanent() {
|
||||||
|
return lblCounterPermanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblTapPermanent() {
|
||||||
|
return lblTapPermanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblUntapPermanent() {
|
||||||
|
return lblUntapPermanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblUnlimitedLands() {
|
||||||
|
return lblUnlimitedLands;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return DevLabel */
|
||||||
|
public DevLabel getLblHumanLife() {
|
||||||
|
return lblHumanLife;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return HashMap<Player, JLabel[]> */
|
||||||
|
public HashMap<Player, JLabel[]> getDetailLabels() {
|
||||||
|
return detailLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Assembles Swing components for "players" panel. */
|
||||||
|
private void populatePnlPlayers() {
|
||||||
|
List<Player> players = AllZone.getPlayersInGame();
|
||||||
|
detailLabels = new HashMap<Player, JLabel[]>();
|
||||||
|
|
||||||
|
for (Player p : players) {
|
||||||
|
// Create and store labels detailing various non-critical player info.
|
||||||
|
InfoLabel name = new InfoLabel();
|
||||||
|
InfoLabel life = new InfoLabel();
|
||||||
|
InfoLabel hand = new InfoLabel();
|
||||||
|
InfoLabel draw = new InfoLabel();
|
||||||
|
detailLabels.put(p, new JLabel[] {life, hand, draw});
|
||||||
|
|
||||||
|
// Set border on bottom label, and larger font on player name
|
||||||
|
draw.setBorder(new MatteBorder(0, 0, 1, 0, skin.getClrBorders()));
|
||||||
|
name.setText(p.getName());
|
||||||
|
name.setFont(skin.getFont1().deriveFont(Font.PLAIN, 14));
|
||||||
|
|
||||||
|
// Add to "players" tab panel
|
||||||
|
String constraints = "w 97%!, gapleft 2%, gapbottom 1%";
|
||||||
|
pnlPlayers.add(name, constraints);
|
||||||
|
pnlPlayers.add(life, constraints);
|
||||||
|
pnlPlayers.add(hand, constraints);
|
||||||
|
pnlPlayers.add(draw, constraints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Assembles Swing components for "dev mode" panel. */
|
||||||
|
private void populatePnlDev() {
|
||||||
|
JPanel viewport = new JPanel();
|
||||||
|
viewport.setLayout(new MigLayout("wrap, insets 0"));
|
||||||
|
viewport.setOpaque(false);
|
||||||
|
|
||||||
|
JScrollPane jsp = new JScrollPane(viewport, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
|
||||||
|
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
|
jsp.setOpaque(false);
|
||||||
|
jsp.getViewport().setOpaque(false);
|
||||||
|
|
||||||
|
pnlDev.add(jsp, "w 100%!, h 100%!");
|
||||||
|
|
||||||
|
lblMilling = new DevLabel("Loss by Milling: Enabled", "Loss by Milling: Disabled");
|
||||||
|
lblHandView = new DevLabel("View Any Hand: Enabled", "View Any Hand: Disabled");
|
||||||
|
lblLibraryView = new DevLabel("View Any Library: Enabled", "View Any Library: Disabled");
|
||||||
|
lblGenerateMana = new DevLabel("Generate Mana");
|
||||||
|
lblSetupGame = new DevLabel("Setup Game State");
|
||||||
|
lblTutor = new DevLabel("Tutor for card");
|
||||||
|
lblCounterPermanent = new DevLabel("Add Counter to Permanent");
|
||||||
|
lblTapPermanent = new DevLabel("Tap Permanent");
|
||||||
|
lblUntapPermanent = new DevLabel("Untap Permanent");
|
||||||
|
lblUnlimitedLands = new DevLabel("Play Unlimited Lands This Turn");
|
||||||
|
lblHumanLife = new DevLabel("Set Player Life");
|
||||||
|
|
||||||
|
String constraints = "w 100%!, gap 0 0 5px 0";
|
||||||
|
viewport.add(lblMilling, constraints);
|
||||||
|
viewport.add(lblHandView, constraints);
|
||||||
|
viewport.add(lblLibraryView, constraints);
|
||||||
|
viewport.add(lblGenerateMana, constraints);
|
||||||
|
viewport.add(lblSetupGame, constraints);
|
||||||
|
viewport.add(lblTutor, constraints);
|
||||||
|
viewport.add(lblCounterPermanent, constraints);
|
||||||
|
viewport.add(lblTapPermanent, constraints);
|
||||||
|
viewport.add(lblUntapPermanent, constraints);
|
||||||
|
viewport.add(lblUnlimitedLands, constraints);
|
||||||
|
viewport.add(lblHumanLife, constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Assembles swing components for "console" panel. */
|
||||||
|
private void populatePnlConsole() {
|
||||||
|
JLabel prompt = new JLabel("IN > ");
|
||||||
|
JTextField input = new JTextField();
|
||||||
|
|
||||||
|
JTextArea log = new JTextArea();
|
||||||
|
log.setBackground(new Color(0, 0, 0, 20));
|
||||||
|
log.setWrapStyleWord(true);
|
||||||
|
log.setLineWrap(true);
|
||||||
|
log.setWrapStyleWord(true);
|
||||||
|
log.setEditable(false);
|
||||||
|
log.setFocusable(false);
|
||||||
|
log.setForeground(skin.getClrText());
|
||||||
|
log.setFont(skin.getFont1().deriveFont(Font.PLAIN, 12));
|
||||||
|
log.setBorder(new MatteBorder(1, 0, 0, 0, skin.getClrBorders()));
|
||||||
|
|
||||||
|
log.setText("Not implemented yet. Input codes entered above. "
|
||||||
|
+ "Output data recorded below.");
|
||||||
|
|
||||||
|
pnlConsole.setLayout(new MigLayout("insets 0, gap 0, wrap 2"));
|
||||||
|
|
||||||
|
pnlConsole.add(prompt, "w 28%!, h 10%!, gapleft 2%, gaptop 2%, gapbottom 2%");
|
||||||
|
pnlConsole.add(input, "w 68%!, gapright 2%, gaptop 2%, gapbottom 2%");
|
||||||
|
pnlConsole.add(log, "w 94%!, h 80%!, gapleft 4%, span 2 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Labels that act as buttons which control dev mode functions. Labels
|
||||||
|
* are used to support multiline text.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DevLabel extends JLabel {
|
||||||
|
private static final long serialVersionUID = 7917311680519060700L;
|
||||||
|
|
||||||
|
private Color defaultBG = Color.green;
|
||||||
|
private Color hoverBG = skin.getClrHover();
|
||||||
|
private boolean enabled;
|
||||||
|
private String enabledText, disabledText;
|
||||||
|
private int w, h, r, i; // Width, height, radius, insets (for paintComponent)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Labels that act as buttons which control dev mode functions. Labels
|
||||||
|
* are used (instead of buttons) to support multiline text.
|
||||||
|
*
|
||||||
|
* Constructor for DevLabel which doesn't use enabled/disabled states;
|
||||||
|
* only single text string required.
|
||||||
|
*
|
||||||
|
* @param s0   String text/tooltip of label
|
||||||
|
*/
|
||||||
|
public DevLabel(String s0) {
|
||||||
|
this(s0, s0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Labels that act as buttons which control dev mode functions. Labels
|
||||||
|
* are used (instead of buttons) to support multiline text.
|
||||||
|
*
|
||||||
|
* This constructor for DevLabels empowers an "enable" state that
|
||||||
|
* displays them as green (enabled) or red (disabled).
|
||||||
|
*
|
||||||
|
* @param en0   String text/tooltip of label, in "enabled" state
|
||||||
|
* @param dis0   String text/tooltip of label, in "disabled" state
|
||||||
|
*/
|
||||||
|
public DevLabel(String en0, String dis0) {
|
||||||
|
super();
|
||||||
|
this.setUI(MultiLineLabelUI.getLabelUI());
|
||||||
|
this.setFont(skin.getFont1().deriveFont(Font.PLAIN, 11));
|
||||||
|
this.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||||
|
this.enabledText = en0;
|
||||||
|
this.disabledText = dis0;
|
||||||
|
this.r = 6; // Radius (for paintComponent)
|
||||||
|
this.i = 2; // Insets (for paintComponent)
|
||||||
|
setEnabled(true);
|
||||||
|
|
||||||
|
this.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
setBackground(hoverBG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
setBackground(defaultBG);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes enabled state per boolean parameter, automatically updating
|
||||||
|
* text string and background color.
|
||||||
|
*
|
||||||
|
* @param b   boolean
|
||||||
|
*/
|
||||||
|
public void setEnabled(boolean b) {
|
||||||
|
String s;
|
||||||
|
if (b) {
|
||||||
|
defaultBG = Color.green;
|
||||||
|
s = enabledText;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
defaultBG = Color.red;
|
||||||
|
s = disabledText;
|
||||||
|
}
|
||||||
|
enabled = b;
|
||||||
|
this.setText(s);
|
||||||
|
this.setToolTipText(s);
|
||||||
|
this.setBackground(defaultBG);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return boolean */
|
||||||
|
public boolean getEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In many cases, a DevLabel state will just be toggling a boolean.
|
||||||
|
* This method sets up and evaluates the condition and toggles as appropriate.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void toggleEnabled() {
|
||||||
|
if (enabled) {
|
||||||
|
setEnabled(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
w = getWidth();
|
||||||
|
h = getHeight();
|
||||||
|
g.setColor(this.getBackground());
|
||||||
|
g.fillRoundRect(i, i, w - 2 * i, h - i, r, r);
|
||||||
|
super.paintComponent(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A quick JLabel for info in "players" panel, to consolidate styling. */
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
private class InfoLabel extends JLabel {
|
||||||
|
public InfoLabel() {
|
||||||
|
super();
|
||||||
|
this.setFont(skin.getFont1().deriveFont(Font.PLAIN, 11));
|
||||||
|
this.setForeground(skin.getClrText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
453
src/main/java/forge/view/match/ViewTopLevel.java
Normal file
@@ -0,0 +1,453 @@
|
|||||||
|
package forge.view.match;
|
||||||
|
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Card;
|
||||||
|
import forge.CardList;
|
||||||
|
import forge.Constant;
|
||||||
|
import forge.Display;
|
||||||
|
import forge.MyButton;
|
||||||
|
import forge.Player;
|
||||||
|
import forge.Singletons;
|
||||||
|
import forge.control.ControlMatchUI;
|
||||||
|
import forge.control.match.ControlCardviewer;
|
||||||
|
import forge.control.match.ControlDock;
|
||||||
|
import forge.control.match.ControlField;
|
||||||
|
import forge.control.match.ControlHand;
|
||||||
|
import forge.control.match.ControlInput;
|
||||||
|
import forge.control.match.ControlTabber;
|
||||||
|
import forge.gui.skin.FPanel;
|
||||||
|
import forge.properties.ForgePreferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* - Lays out battle, sidebar, user areas in locked % vals and repaints
|
||||||
|
* as necessary.<br>
|
||||||
|
* - Instantiates top-level controller for match UI.<br>
|
||||||
|
* - Has access methods for all child controllers<br>
|
||||||
|
* - Implements Display interface used in singleton pattern
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ViewTopLevel extends FPanel implements Display {
|
||||||
|
private ViewAreaSidebar areaSidebar;
|
||||||
|
private ViewAreaBattlefield areaBattle;
|
||||||
|
private ViewAreaUser areaUser;
|
||||||
|
|
||||||
|
private int w, h;
|
||||||
|
private static final double SIDEBAR_W_PCT = 0.16;
|
||||||
|
private static final double USER_H_PCT = 0.27;
|
||||||
|
private ControlMatchUI control;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* - Lays out battle, sidebar, user areas in locked % vals and repaints
|
||||||
|
* as necessary.<br>
|
||||||
|
* - Instantiates top-level controller for match UI.<br>
|
||||||
|
* - Has access methods for all child controllers<br>
|
||||||
|
* - Implements Display interface used in singleton pattern
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ViewTopLevel() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Set properties
|
||||||
|
setOpaque(false);
|
||||||
|
setBGTexture(AllZone.getSkin().getTexture1());
|
||||||
|
setBGImg(AllZone.getSkin().getMatchBG());
|
||||||
|
setLayout(null);
|
||||||
|
|
||||||
|
// areaBattle: holds fields for all players in match.
|
||||||
|
areaBattle = new ViewAreaBattlefield();
|
||||||
|
areaBattle.setBounds(0, 0, getWidth() / 2, getHeight() / 2);
|
||||||
|
add(areaBattle);
|
||||||
|
|
||||||
|
// areaSidebar: holds card detail, info tabber.
|
||||||
|
areaSidebar = new ViewAreaSidebar();
|
||||||
|
areaSidebar.setBounds(0, 0, getWidth() / 2, getHeight() / 2);
|
||||||
|
add(areaSidebar);
|
||||||
|
|
||||||
|
// areaUser: holds input, hand, dock.
|
||||||
|
areaUser = new ViewAreaUser();
|
||||||
|
areaUser.setBounds(0, 0, getWidth() / 2, getHeight() / 2);
|
||||||
|
add(areaUser);
|
||||||
|
|
||||||
|
// After all components are in place, instantiate controller.
|
||||||
|
control = new ControlMatchUI(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The null layout used in MatchFrame has zones split into percentage values
|
||||||
|
* to prevent child components pushing around the parent layout. A single
|
||||||
|
* instance of BodyPanel holds these zones, and handles the percentage resizing.
|
||||||
|
*
|
||||||
|
* @param g   Graphics object
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
w = getWidth();
|
||||||
|
h = getHeight();
|
||||||
|
|
||||||
|
// Set % boundaries of layout control layer
|
||||||
|
areaBattle.setBounds(0, 0, (int) (w * (1 - SIDEBAR_W_PCT)),
|
||||||
|
(int) (h * (1 - USER_H_PCT)));
|
||||||
|
areaSidebar.setBounds((int) (w * (1 - SIDEBAR_W_PCT)), 0,
|
||||||
|
(int) (w * SIDEBAR_W_PCT), h);
|
||||||
|
areaUser.setBounds(0, (int) (h * (1 - USER_H_PCT)),
|
||||||
|
(int) (w * (1 - SIDEBAR_W_PCT)), (int) (h * USER_H_PCT));
|
||||||
|
areaBattle.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========== Retrieval functions for easier interation with children panels.
|
||||||
|
/** @return ViewAreaSidebar */
|
||||||
|
public ViewAreaSidebar getAreaSidebar() {
|
||||||
|
return areaSidebar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ViewAreaBattlefield */
|
||||||
|
public ViewAreaBattlefield getAreaBattlefield() {
|
||||||
|
return areaBattle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ViewAreaUser */
|
||||||
|
public ViewAreaUser getAreaUser() {
|
||||||
|
return areaUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves top level controller (actions, observers, etc.)
|
||||||
|
* for this UI.
|
||||||
|
*
|
||||||
|
* @return {@link java.util.List<MatchPlayer>}
|
||||||
|
*/
|
||||||
|
public ControlMatchUI getController() {
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlCardviewer */
|
||||||
|
public ControlCardviewer getCardviewerController() {
|
||||||
|
return areaSidebar.getCardviewer().getController();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlTabber */
|
||||||
|
public ControlTabber getTabberController() {
|
||||||
|
return areaSidebar.getTabber().getController();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlInput */
|
||||||
|
public ControlInput getInputController() {
|
||||||
|
return areaUser.getPnlInput().getController();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlHand */
|
||||||
|
public ControlHand getHandController() {
|
||||||
|
return areaUser.getPnlHand().getController();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ControlDock */
|
||||||
|
public ControlDock getDockController() {
|
||||||
|
return areaUser.getPnlDock().getController();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return List<ControlField> */
|
||||||
|
public List<ControlField> getFieldControllers() {
|
||||||
|
List<ViewField> fields = areaBattle.getFields();
|
||||||
|
List<ControlField> controllers = new ArrayList<ControlField>();
|
||||||
|
|
||||||
|
for (ViewField f : fields) {
|
||||||
|
controllers.add(f.getController());
|
||||||
|
}
|
||||||
|
|
||||||
|
return controllers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return List<ViewField> */
|
||||||
|
public List<ViewField> getFieldViews() {
|
||||||
|
return areaBattle.getFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
//========== Input panel and human hand retrieval functions
|
||||||
|
// Also due to be deprecated. Access should be handled by child component
|
||||||
|
// view and/or controller.
|
||||||
|
|
||||||
|
/** @return <b>JTextArea</b> Message area of input panel. */
|
||||||
|
public JTextArea getPnlMessage() {
|
||||||
|
return areaUser.getPnlInput().getTarMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return <b>ViewHand</b> Retrieves player hand panel. */
|
||||||
|
public ViewHand getPnlHand() {
|
||||||
|
return areaUser.getPnlHand();
|
||||||
|
}
|
||||||
|
|
||||||
|
//========== The following methods are required by the Display interface.
|
||||||
|
// To fit the UI MVC architecture with the previous "mixed nuts" architecture,
|
||||||
|
// these methods are temporarily required. However, since they are a mix of
|
||||||
|
// view and control functionalities, they are ALL on the "to-be-deprecated" list.
|
||||||
|
// The Display interface is to be reworked, eventually, with a better name
|
||||||
|
// and with interfaces for every screen in the entire UI.
|
||||||
|
// Doublestrike 23-10-11
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required by Display interface.
|
||||||
|
* Due to be deprecated in favor of more semantic getBtnCancel().
|
||||||
|
*
|
||||||
|
* @return MyButton
|
||||||
|
*/
|
||||||
|
public MyButton getButtonCancel() {
|
||||||
|
MyButton cancel = new MyButton() {
|
||||||
|
public void select() {
|
||||||
|
getInputController().getInputControl().selectButtonCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSelectable() {
|
||||||
|
return areaUser.getPnlInput().getBtnCancel().isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectable(final boolean b) {
|
||||||
|
areaUser.getPnlInput().getBtnCancel().setEnabled(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return areaUser.getPnlInput().getBtnCancel().getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(final String text) {
|
||||||
|
areaUser.getPnlInput().getBtnCancel().setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
areaUser.getPnlInput().getBtnCancel().setText("Cancel");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required by Display interface.
|
||||||
|
* Due to be deprecated in favor of more semantic getBtnOK().
|
||||||
|
*
|
||||||
|
* @return MyButton
|
||||||
|
*/
|
||||||
|
public MyButton getButtonOK() {
|
||||||
|
MyButton ok = new MyButton() {
|
||||||
|
public void select() {
|
||||||
|
getInputController().getInputControl().selectButtonOK();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSelectable() {
|
||||||
|
return areaUser.getPnlInput().getBtnOK().isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectable(final boolean b) {
|
||||||
|
areaUser.getPnlInput().getBtnOK().setEnabled(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return areaUser.getPnlInput().getBtnOK().getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(final String text) {
|
||||||
|
areaUser.getPnlInput().getBtnOK().setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
areaUser.getPnlInput().getBtnOK().setText("OK");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required by Display interface.
|
||||||
|
* Due to be deprecated: is now and should be handled by ControlMatchUI.
|
||||||
|
*
|
||||||
|
* @param s   Message string
|
||||||
|
*/
|
||||||
|
public void showMessage(String s) {
|
||||||
|
getPnlMessage().setText(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required by Display interface.
|
||||||
|
* Due to be deprecated: should be handled by ControlMatchUI.
|
||||||
|
*
|
||||||
|
* @param s   Message string
|
||||||
|
*/
|
||||||
|
public void showCombat(String s) {
|
||||||
|
getTabberController().getView().updateCombat(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required by Display interface.
|
||||||
|
* Due to be deprecated: should be handled by a control class, and
|
||||||
|
* poorly named; "decking" == "milling" in preferences, same terminology
|
||||||
|
* should be used throughout project for obvious reasons. Unless "decking"
|
||||||
|
* is already the correct terminology, in which case, everything else is
|
||||||
|
* poorly named.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean canLoseByDecking() {
|
||||||
|
return Constant.Runtime.MILL[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>loadPrefs.</p>
|
||||||
|
* Required by Display interface.
|
||||||
|
* Due to be deprecated: will be handled by ControlMatchUI.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return boolean.
|
||||||
|
*/
|
||||||
|
public final boolean loadPrefs() {
|
||||||
|
ForgePreferences fp = Singletons.getModel().getPreferences();
|
||||||
|
List<ViewField> fieldViews = getFieldViews();
|
||||||
|
|
||||||
|
// AI field is at index [0]
|
||||||
|
fieldViews.get(0).getLblUpkeep().setEnabled(fp.isbAIUpkeep());
|
||||||
|
fieldViews.get(0).getLblDraw().setEnabled(fp.isbAIDraw());
|
||||||
|
fieldViews.get(0).getLblEndTurn().setEnabled(fp.isbAIEOT());
|
||||||
|
fieldViews.get(0).getLblBeginCombat().setEnabled(fp.isbAIBeginCombat());
|
||||||
|
fieldViews.get(0).getLblEndCombat().setEnabled(fp.isbAIEndCombat());
|
||||||
|
|
||||||
|
// Human field is at index [1]
|
||||||
|
fieldViews.get(1).getLblUpkeep().setEnabled(fp.isbHumanUpkeep());
|
||||||
|
fieldViews.get(1).getLblDraw().setEnabled(fp.isbHumanDraw());
|
||||||
|
fieldViews.get(1).getLblEndTurn().setEnabled(fp.isbHumanEOT());
|
||||||
|
fieldViews.get(1).getLblBeginCombat().setEnabled(fp.isbHumanBeginCombat());
|
||||||
|
fieldViews.get(1).getLblEndCombat().setEnabled(fp.isbHumanEndCombat());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>savePrefs.</p>
|
||||||
|
* Required by Display interface.
|
||||||
|
* Due to be deprecated: will be handled by ControlMatchUI.
|
||||||
|
* Also, this functionality is already performed elsewhere in the code base.
|
||||||
|
* Furthermore, there's a strong possibility this will need bo be broken
|
||||||
|
* down and can't be in one place - e.g. keyboard shortcuts are
|
||||||
|
* saved after they're edited.
|
||||||
|
*
|
||||||
|
* @return a boolean.
|
||||||
|
*/
|
||||||
|
public final boolean savePrefs() {
|
||||||
|
ForgePreferences fp = Singletons.getModel().getPreferences();
|
||||||
|
List<ViewField> fieldViews = getFieldViews();
|
||||||
|
|
||||||
|
// AI field is at index [0]
|
||||||
|
fp.setbAIUpkeep(fieldViews.get(0).getLblUpkeep().getEnabled());
|
||||||
|
fp.setbAIDraw(fieldViews.get(0).getLblDraw().getEnabled());
|
||||||
|
fp.setbAIEOT(fieldViews.get(0).getLblEndTurn().getEnabled());
|
||||||
|
fp.setbAIBeginCombat(fieldViews.get(0).getLblBeginCombat().getEnabled());
|
||||||
|
fp.setbAIEndCombat(fieldViews.get(0).getLblEndCombat().getEnabled());
|
||||||
|
|
||||||
|
// Human field is at index [1]
|
||||||
|
fp.setbHumanUpkeep(fieldViews.get(1).getLblUpkeep().getEnabled());
|
||||||
|
fp.setbHumanDraw(fieldViews.get(1).getLblDraw().getEnabled());
|
||||||
|
fp.setbHumanEOT(fieldViews.get(1).getLblEndTurn().getEnabled());
|
||||||
|
fp.setbHumanBeginCombat(fieldViews.get(1).getLblBeginCombat().getEnabled());
|
||||||
|
fp.setbHumanEndCombat(fieldViews.get(1).getLblEndCombat().getEnabled());
|
||||||
|
|
||||||
|
Constant.Runtime.MILL[0] = this.getTabberController().getView().getLblMilling().getEnabled();
|
||||||
|
Constant.Runtime.HANDVIEW[0] = this.getTabberController().getView().getLblHandView().getEnabled();
|
||||||
|
Constant.Runtime.LIBRARYVIEW[0] = this.getTabberController().getView().getLblLibraryView().getEnabled();
|
||||||
|
|
||||||
|
fp.setMillingLossCondition(Constant.Runtime.MILL[0]);
|
||||||
|
fp.setHandView(Constant.Runtime.HANDVIEW[0]);
|
||||||
|
fp.setLibraryView(Constant.Runtime.LIBRARYVIEW[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>stopAtPhase.</p>
|
||||||
|
* Required by Display interface.
|
||||||
|
* Due to be deprecated: should be handled by control class.
|
||||||
|
*
|
||||||
|
* @param turn   Player object...more info needed
|
||||||
|
* @param phase   A string...more info needed
|
||||||
|
* @return a boolean.
|
||||||
|
*/
|
||||||
|
public final boolean stopAtPhase(final Player turn, final String phase) {
|
||||||
|
List<ControlField> fieldControllers = getFieldControllers();
|
||||||
|
|
||||||
|
// AI field is at index [0]
|
||||||
|
if (turn.isComputer()) {
|
||||||
|
if (phase.equals(Constant.Phase.END_OF_TURN)) {
|
||||||
|
return fieldControllers.get(0).getView().getLblEndTurn().getEnabled();
|
||||||
|
} else if (phase.equals(Constant.Phase.UPKEEP)) {
|
||||||
|
return fieldControllers.get(0).getView().getLblUpkeep().getEnabled();
|
||||||
|
} else if (phase.equals(Constant.Phase.DRAW)) {
|
||||||
|
return fieldControllers.get(0).getView().getLblDraw().getEnabled();
|
||||||
|
} else if (phase.equals(Constant.Phase.COMBAT_BEGIN)) {
|
||||||
|
return fieldControllers.get(0).getView().getLblBeginCombat().getEnabled();
|
||||||
|
} else if (phase.equals(Constant.Phase.COMBAT_END)) {
|
||||||
|
return fieldControllers.get(0).getView().getLblEndCombat().getEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Human field is at index [1]
|
||||||
|
else {
|
||||||
|
if (phase.equals(Constant.Phase.END_OF_TURN)) {
|
||||||
|
return fieldControllers.get(1).getView().getLblEndTurn().getEnabled();
|
||||||
|
} else if (phase.equals(Constant.Phase.UPKEEP)) {
|
||||||
|
return fieldControllers.get(1).getView().getLblUpkeep().getEnabled();
|
||||||
|
} else if (phase.equals(Constant.Phase.DRAW)) {
|
||||||
|
return fieldControllers.get(1).getView().getLblDraw().getEnabled();
|
||||||
|
} else if (phase.equals(Constant.Phase.COMBAT_BEGIN)) {
|
||||||
|
return fieldControllers.get(1).getView().getLblBeginCombat().getEnabled();
|
||||||
|
} else if (phase.equals(Constant.Phase.COMBAT_END)) {
|
||||||
|
return fieldControllers.get(1).getView().getLblEndCombat().getEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required by display interface.
|
||||||
|
* Due to be deprecated: handled by control class.
|
||||||
|
*
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public final Card getCard() {
|
||||||
|
System.err.println("ViewTopLevel > getCard: Something should happen here!");
|
||||||
|
new Exception().printStackTrace();
|
||||||
|
return null; //new Card(); //detail.getCard();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required by display interface.
|
||||||
|
* Due to be deprecated: already handled by controller class.
|
||||||
|
*
|
||||||
|
* @param card   a card
|
||||||
|
*/
|
||||||
|
public final void setCard(final Card card) {
|
||||||
|
System.err.println("ViewTopLevel > getCard: Something should happen here!");
|
||||||
|
new Exception().printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required by Display interface.
|
||||||
|
* Assigns damage to multiple blockers.
|
||||||
|
* Due to be deprecated: Gui_MultipleBlockers4 says "very hacky"; needs
|
||||||
|
* rewriting.
|
||||||
|
*
|
||||||
|
* @param attacker   Card object
|
||||||
|
* @param blockers   Card objects in CardList form
|
||||||
|
* @param damage   int
|
||||||
|
*/
|
||||||
|
public final void assignDamage(final Card attacker, final CardList blockers, final int damage) {
|
||||||
|
if (damage <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//new Gui_MultipleBlockers4(attacker, blockers, damage, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -97,7 +97,7 @@ public class ApplicationView implements FView {
|
|||||||
final ForgePreferences preferences = model.getPreferences();
|
final ForgePreferences preferences = model.getPreferences();
|
||||||
|
|
||||||
OldGuiNewGame.getUseLAFFonts().setSelected(preferences.isLafFonts());
|
OldGuiNewGame.getUseLAFFonts().setSelected(preferences.isLafFonts());
|
||||||
// newGuiCheckBox.setSelected(preferences.newGui);
|
OldGuiNewGame.getOldGuiCheckBox().setSelected(preferences.isOldGui());
|
||||||
OldGuiNewGame.getSmoothLandCheckBox().setSelected(preferences.isStackAiLand());
|
OldGuiNewGame.getSmoothLandCheckBox().setSelected(preferences.isStackAiLand());
|
||||||
OldGuiNewGame.getDevModeCheckBox().setSelected(preferences.isDeveloperMode());
|
OldGuiNewGame.getDevModeCheckBox().setSelected(preferences.isDeveloperMode());
|
||||||
OldGuiNewGame.getCardOverlay().setSelected(preferences.isCardOverlay());
|
OldGuiNewGame.getCardOverlay().setSelected(preferences.isCardOverlay());
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ import forge.ImageCache;
|
|||||||
import forge.MyRandom;
|
import forge.MyRandom;
|
||||||
import forge.PlayerType;
|
import forge.PlayerType;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
|
import forge.control.ControlAllUI;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.DeckGeneration;
|
import forge.deck.DeckGeneration;
|
||||||
import forge.deck.DeckManager;
|
import forge.deck.DeckManager;
|
||||||
@@ -124,8 +125,8 @@ public class OldGuiNewGame extends JFrame {
|
|||||||
|
|
||||||
// @SuppressWarnings("unused")
|
// @SuppressWarnings("unused")
|
||||||
// titledBorder2
|
// titledBorder2
|
||||||
/** Constant <code>newGuiCheckBox</code>. */
|
/** Constant <code>oldGuiCheckBox</code>. */
|
||||||
// private static JCheckBox newGuiCheckBox = new JCheckBox("", true);
|
private static JCheckBox oldGuiCheckBox = new JCheckBox("", false);
|
||||||
/** Constant <code>smoothLandCheckBox</code>. */
|
/** Constant <code>smoothLandCheckBox</code>. */
|
||||||
private static JCheckBox smoothLandCheckBox = new JCheckBox("", false);
|
private static JCheckBox smoothLandCheckBox = new JCheckBox("", false);
|
||||||
/** Constant <code>devModeCheckBox</code>. */
|
/** Constant <code>devModeCheckBox</code>. */
|
||||||
@@ -556,7 +557,7 @@ public class OldGuiNewGame extends JFrame {
|
|||||||
ForgeProps.getLocalized(NewConstants.Lang.OldGuiNewGame.NewGameText.SETTINGS));
|
ForgeProps.getLocalized(NewConstants.Lang.OldGuiNewGame.NewGameText.SETTINGS));
|
||||||
this.jPanel3.setLayout(new MigLayout("align center"));
|
this.jPanel3.setLayout(new MigLayout("align center"));
|
||||||
|
|
||||||
// newGuiCheckBox.setText(ForgeProps.getLocalized(NEW_GAME_TEXT.NEW_GUI));
|
oldGuiCheckBox.setText(ForgeProps.getLocalized(NewConstants.Lang.OldGuiNewGame.NewGameText.OLD_GUI));
|
||||||
OldGuiNewGame.getSmoothLandCheckBox().setText(
|
OldGuiNewGame.getSmoothLandCheckBox().setText(
|
||||||
ForgeProps.getLocalized(NewConstants.Lang.OldGuiNewGame.NewGameText.AI_LAND));
|
ForgeProps.getLocalized(NewConstants.Lang.OldGuiNewGame.NewGameText.AI_LAND));
|
||||||
|
|
||||||
@@ -639,7 +640,7 @@ public class OldGuiNewGame extends JFrame {
|
|||||||
|
|
||||||
this.getContentPane().add(this.jPanel3, "span 2, grow");
|
this.getContentPane().add(this.jPanel3, "span 2, grow");
|
||||||
|
|
||||||
// jPanel3.add(newGuiCheckBox, "wrap");
|
jPanel3.add(oldGuiCheckBox, "wrap");
|
||||||
this.jPanel3.add(OldGuiNewGame.getSmoothLandCheckBox(), "wrap");
|
this.jPanel3.add(OldGuiNewGame.getSmoothLandCheckBox(), "wrap");
|
||||||
this.jPanel3.add(OldGuiNewGame.getDevModeCheckBox(), "wrap");
|
this.jPanel3.add(OldGuiNewGame.getDevModeCheckBox(), "wrap");
|
||||||
this.jPanel3.add(OldGuiNewGame.getUpldDrftCheckBox(), "wrap");
|
this.jPanel3.add(OldGuiNewGame.getUpldDrftCheckBox(), "wrap");
|
||||||
@@ -865,15 +866,19 @@ public class OldGuiNewGame extends JFrame {
|
|||||||
}
|
}
|
||||||
} // else
|
} // else
|
||||||
|
|
||||||
// DO NOT CHANGE THIS ORDER, GuiDisplay needs to be created before cards
|
Constant.Runtime.OLDGUI[0] = oldGuiCheckBox.isSelected();
|
||||||
// are added
|
|
||||||
// Constant.Runtime.DevMode[0] = devModeCheckBox.isSelected();
|
|
||||||
|
|
||||||
// if (newGuiCheckBox.isSelected())
|
if (Constant.Runtime.OLDGUI[0]) {
|
||||||
AllZone.setDisplay(new GuiDisplay());
|
AllZone.setDisplay(new GuiDisplay());
|
||||||
// else AllZone.setDisplay(new GuiDisplay3());
|
}
|
||||||
|
else {
|
||||||
|
ControlAllUI ui = new ControlAllUI();
|
||||||
|
AllZone.setDisplay(ui.getMatchView());
|
||||||
|
ui.getMatchController().initMatch();
|
||||||
|
}
|
||||||
|
|
||||||
Constant.Runtime.SMOOTH[0] = OldGuiNewGame.getSmoothLandCheckBox().isSelected();
|
Constant.Runtime.SMOOTH[0] = OldGuiNewGame.getSmoothLandCheckBox().isSelected();
|
||||||
|
//Constant.Runtime.DEV_MODE[0] = OldGuiNewGame.devModeCheckBox.isSelected();
|
||||||
|
|
||||||
AllZone.getGameAction().newGame(Constant.Runtime.HUMAN_DECK[0], Constant.Runtime.COMPUTER_DECK[0]);
|
AllZone.getGameAction().newGame(Constant.Runtime.HUMAN_DECK[0], Constant.Runtime.COMPUTER_DECK[0]);
|
||||||
AllZone.getDisplay().setVisible(true);
|
AllZone.getDisplay().setVisible(true);
|
||||||
@@ -1714,7 +1719,7 @@ public class OldGuiNewGame extends JFrame {
|
|||||||
final ForgePreferences preferences = Singletons.getModel().getPreferences();
|
final ForgePreferences preferences = Singletons.getModel().getPreferences();
|
||||||
preferences.setLaf(UIManager.getLookAndFeel().getClass().getName());
|
preferences.setLaf(UIManager.getLookAndFeel().getClass().getName());
|
||||||
preferences.setLafFonts(OldGuiNewGame.getUseLAFFonts().isSelected());
|
preferences.setLafFonts(OldGuiNewGame.getUseLAFFonts().isSelected());
|
||||||
// preferences.newGui = newGuiCheckBox.isSelected();
|
preferences.setOldGui(oldGuiCheckBox.isSelected());
|
||||||
preferences.setStackAiLand(OldGuiNewGame.getSmoothLandCheckBox().isSelected());
|
preferences.setStackAiLand(OldGuiNewGame.getSmoothLandCheckBox().isSelected());
|
||||||
preferences.setMillingLossCondition(Constant.Runtime.MILL[0]);
|
preferences.setMillingLossCondition(Constant.Runtime.MILL[0]);
|
||||||
preferences.setDeveloperMode(Constant.Runtime.DEV_MODE[0]);
|
preferences.setDeveloperMode(Constant.Runtime.DEV_MODE[0]);
|
||||||
@@ -2000,4 +2005,8 @@ public class OldGuiNewGame extends JFrame {
|
|||||||
// name.
|
// name.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return JCheckBox */
|
||||||
|
public static JCheckBox getOldGuiCheckBox() {
|
||||||
|
return OldGuiNewGame.oldGuiCheckBox;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class SplashFrame extends JFrame {
|
|||||||
this.setUndecorated(true);
|
this.setUndecorated(true);
|
||||||
|
|
||||||
// Set preferred JFrame properties.
|
// Set preferred JFrame properties.
|
||||||
final ImageIcon bgIcon = skin.getSplash();
|
final ImageIcon bgIcon = skin.getSplashBG();
|
||||||
final int splashWidthPx = bgIcon.getIconWidth();
|
final int splashWidthPx = bgIcon.getIconWidth();
|
||||||
final int splashHeightPx = bgIcon.getIconHeight();
|
final int splashHeightPx = bgIcon.getIconHeight();
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import javax.swing.border.AbstractBorder;
|
|||||||
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import forge.AllZone;
|
import forge.AllZone;
|
||||||
|
import forge.Constant;
|
||||||
import forge.Phase;
|
import forge.Phase;
|
||||||
import forge.Player;
|
import forge.Player;
|
||||||
import forge.gui.skin.FButton;
|
import forge.gui.skin.FButton;
|
||||||
@@ -24,6 +25,7 @@ import forge.gui.skin.FPanel;
|
|||||||
import forge.properties.ForgeProps;
|
import forge.properties.ForgeProps;
|
||||||
import forge.properties.NewConstants.Lang.WinLoseFrame.WinLoseText;
|
import forge.properties.NewConstants.Lang.WinLoseFrame.WinLoseText;
|
||||||
import forge.quest.data.QuestMatchState;
|
import forge.quest.data.QuestMatchState;
|
||||||
|
import forge.view.match.ViewTopLevel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -88,7 +90,7 @@ public class WinLoseFrame extends JFrame {
|
|||||||
|
|
||||||
// Place all content in FPanel
|
// Place all content in FPanel
|
||||||
final FPanel contentPanel = new FPanel(new MigLayout("wrap, fill, insets 20 0 10 10"));
|
final FPanel contentPanel = new FPanel(new MigLayout("wrap, fill, insets 20 0 10 10"));
|
||||||
contentPanel.setBGImg(AllZone.getSkin().getTexture1());
|
contentPanel.setBGTexture(AllZone.getSkin().getTexture1());
|
||||||
contentPanel.setBorder(new WinLoseBorder());
|
contentPanel.setBorder(new WinLoseBorder());
|
||||||
this.getContentPane().add(contentPanel);
|
this.getContentPane().add(contentPanel);
|
||||||
|
|
||||||
@@ -271,8 +273,17 @@ public class WinLoseFrame extends JFrame {
|
|||||||
* @return {@link javax.swing.JFrame} display frame
|
* @return {@link javax.swing.JFrame} display frame
|
||||||
*/
|
*/
|
||||||
final JFrame closeWinLoseFrame() {
|
final JFrame closeWinLoseFrame() {
|
||||||
|
JFrame frame;
|
||||||
|
|
||||||
// Issue 147 - keep battlefield up following win/loss
|
// Issue 147 - keep battlefield up following win/loss
|
||||||
final JFrame frame = (JFrame) AllZone.getDisplay();
|
if (Constant.Runtime.OLDGUI[0]) {
|
||||||
|
frame = (JFrame) AllZone.getDisplay();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ViewTopLevel temp = (ViewTopLevel) AllZone.getDisplay();
|
||||||
|
frame = (JFrame) temp.getParent().getParent().getParent().getParent();
|
||||||
|
}
|
||||||
|
|
||||||
frame.dispose();
|
frame.dispose();
|
||||||
frame.setEnabled(true);
|
frame.setEnabled(true);
|
||||||
this.dispose();
|
this.dispose();
|
||||||
|
|||||||
382
src/main/java/forge/view/toolbox/CardDetailPanel.java
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
package forge.view.toolbox;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.ScrollPaneConstants;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Card;
|
||||||
|
import forge.CardContainer;
|
||||||
|
import forge.Constant.Zone;
|
||||||
|
import forge.Counters;
|
||||||
|
import forge.GameEntity;
|
||||||
|
import forge.GuiDisplayUtil;
|
||||||
|
import forge.gui.skin.FSkin;
|
||||||
|
|
||||||
|
/** Shows details of card if moused over. */
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class CardDetailPanel extends JPanel implements CardContainer {
|
||||||
|
private Card card = null;
|
||||||
|
private JLabel lblCardName, lblCardCost, lblCardType,
|
||||||
|
lblCardID, lblCardPT, lblCardSet, lblCardDmg1, lblCardDmg2;
|
||||||
|
private JTextArea tarInfo;
|
||||||
|
private static final Color PURPLE = new Color(14381203);
|
||||||
|
|
||||||
|
private FSkin skin;
|
||||||
|
private Font f;
|
||||||
|
private Color foreground;
|
||||||
|
private Color zebra;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
public CardDetailPanel() {
|
||||||
|
super();
|
||||||
|
setLayout(new MigLayout("wrap, insets 0, gap 0"));
|
||||||
|
|
||||||
|
// Styles used in DetailLabel class
|
||||||
|
skin = AllZone.getSkin();
|
||||||
|
f = skin.getFont1().deriveFont(Font.PLAIN, 11);
|
||||||
|
foreground = skin.getClrText();
|
||||||
|
zebra = skin.getClrZebra();
|
||||||
|
|
||||||
|
// DetailLabel instances (true = zebra stripe)
|
||||||
|
lblCardName = new DetailLabel();
|
||||||
|
lblCardCost = new DetailLabel();
|
||||||
|
lblCardType = new DetailLabel();
|
||||||
|
lblCardPT = new DetailLabel();
|
||||||
|
lblCardDmg1 = new DetailLabel();
|
||||||
|
lblCardDmg2 = new DetailLabel();
|
||||||
|
lblCardID = new DetailLabel();
|
||||||
|
lblCardSet = new DetailLabel();
|
||||||
|
|
||||||
|
// Info text area
|
||||||
|
tarInfo = new JTextArea();
|
||||||
|
tarInfo.setFont(f);
|
||||||
|
tarInfo.setLineWrap(true);
|
||||||
|
tarInfo.setWrapStyleWord(true);
|
||||||
|
tarInfo.setFocusable(false);
|
||||||
|
|
||||||
|
add(lblCardName, "w 100%!");
|
||||||
|
add(lblCardCost, "w 100%!");
|
||||||
|
add(lblCardType, "w 100%!");
|
||||||
|
add(lblCardPT, "w 100%!");
|
||||||
|
add(lblCardDmg1, "w 100%!");
|
||||||
|
add(lblCardDmg2, "w 100%!");
|
||||||
|
add(lblCardID, "w 100%!");
|
||||||
|
add(lblCardSet, "w 100%!");
|
||||||
|
add(new JScrollPane(tarInfo,
|
||||||
|
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
|
||||||
|
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER), "w 100%!, h 45%!, south");
|
||||||
|
setCard(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fairly long method testing conditions determining which details to show.
|
||||||
|
*
|
||||||
|
* @param c   Card obj
|
||||||
|
*/
|
||||||
|
public void setCard(Card c) {
|
||||||
|
lblCardName.setText(" ");
|
||||||
|
lblCardCost.setText(" ");
|
||||||
|
lblCardType.setText(" ");
|
||||||
|
lblCardPT.setText(" ");
|
||||||
|
lblCardDmg1.setText(" ");
|
||||||
|
lblCardDmg2.setText(" ");
|
||||||
|
lblCardID.setText(" ");
|
||||||
|
lblCardSet.setText(" ");
|
||||||
|
lblCardSet.setOpaque(true);
|
||||||
|
lblCardSet.setBorder(null);
|
||||||
|
tarInfo.setText(" ");
|
||||||
|
|
||||||
|
this.card = c;
|
||||||
|
if (card == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean faceDown = card.isFaceDown() && card.getController() != AllZone.getHumanPlayer();
|
||||||
|
|
||||||
|
if (!faceDown) {
|
||||||
|
lblCardName.setText(card.getName());
|
||||||
|
if (!card.getManaCost().equals("") && !card.isLand()) {
|
||||||
|
lblCardCost.setText(card.getManaCost());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lblCardName.setText("Morph");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!faceDown) {
|
||||||
|
lblCardType.setText(GuiDisplayUtil.formatCardType(card));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lblCardType.setText("Creature");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (card.isCreature()) {
|
||||||
|
lblCardPT.setText(card.getNetAttack() + " / " + card.getNetDefense());
|
||||||
|
lblCardDmg1.setText("Damage: " + card.getDamage());
|
||||||
|
lblCardDmg2.setText("Assigned Damage: " + card.getTotalAssignedDamage());
|
||||||
|
}
|
||||||
|
if (card.isPlaneswalker()) {
|
||||||
|
lblCardDmg2.setText("Assigned Damage: " + card.getTotalAssignedDamage());
|
||||||
|
}
|
||||||
|
|
||||||
|
lblCardID.setText("Card ID " + card.getUniqueNumber());
|
||||||
|
|
||||||
|
// Rarity and set of a face down card should not be visible to the opponent
|
||||||
|
if (!card.isFaceDown() || card.getController().isHuman()) {
|
||||||
|
String s = card.getCurSetCode();
|
||||||
|
if (s.equals("")) {
|
||||||
|
lblCardSet.setText("---");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lblCardSet.setText(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String csr = card.getCurSetRarity();
|
||||||
|
if (csr.equals("Common") || csr.equals("Land")) {
|
||||||
|
lblCardSet.setBackground(Color.BLACK);
|
||||||
|
lblCardSet.setForeground(Color.WHITE);
|
||||||
|
//lblCardSet.setBorder(BorderFactory.createLineBorder(Color.WHITE));
|
||||||
|
} else if (csr.equals("Uncommon")) {
|
||||||
|
lblCardSet.setBackground(Color.LIGHT_GRAY);
|
||||||
|
lblCardSet.setForeground(Color.BLACK);
|
||||||
|
//lblCardSet.setBorder(BorderFactory.createLineBorder(Color.BLACK));
|
||||||
|
} else if (csr.equals("Rare")) {
|
||||||
|
lblCardSet.setBackground(Color.YELLOW);
|
||||||
|
lblCardSet.setForeground(Color.BLACK);
|
||||||
|
//lblCardSet.setBorder(BorderFactory.createLineBorder(Color.BLACK));
|
||||||
|
} else if (csr.equals("Mythic")) {
|
||||||
|
lblCardSet.setBackground(Color.RED);
|
||||||
|
lblCardSet.setForeground(Color.BLACK);
|
||||||
|
//lblCardSet.setBorder(BorderFactory.createLineBorder(Color.BLACK));
|
||||||
|
} else if (csr.equals("Special")) {
|
||||||
|
// "Timeshifted" or other Special Rarity Cards
|
||||||
|
lblCardSet.setBackground(PURPLE);
|
||||||
|
lblCardSet.setForeground(Color.BLACK);
|
||||||
|
//lblCardSet.setBorder(BorderFactory.createLineBorder(Color.BLACK));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the card text
|
||||||
|
StringBuilder str = new StringBuilder();
|
||||||
|
|
||||||
|
// Token
|
||||||
|
if (card.isToken()) { str.append("Token"); }
|
||||||
|
|
||||||
|
if (!faceDown) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
String text = card.getText();
|
||||||
|
|
||||||
|
//LEVEL [0-9]+-[0-9]+
|
||||||
|
//LEVEL [0-9]+\+
|
||||||
|
String regex = "LEVEL [0-9]+-[0-9]+ ";
|
||||||
|
text = text.replaceAll(regex, "$0\r\n");
|
||||||
|
|
||||||
|
regex = "LEVEL [0-9]+\\+ ";
|
||||||
|
text = text.replaceAll(regex, "\r\n$0\r\n");
|
||||||
|
|
||||||
|
// Displays keywords that have dots in them a little better:
|
||||||
|
regex = "\\., ";
|
||||||
|
text = text.replaceAll(regex, ".\r\n");
|
||||||
|
|
||||||
|
str.append(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phasing
|
||||||
|
if (card.isPhasedOut()) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("Phased Out");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Counter text
|
||||||
|
Counters[] counters = Counters.values();
|
||||||
|
for (Counters counter : counters) {
|
||||||
|
if (card.getCounters(counter) != 0) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append(counter.getName() + " counters: ");
|
||||||
|
str.append(card.getCounters(counter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regeneration Shields
|
||||||
|
int regenShields = card.getShield();
|
||||||
|
if (regenShields > 0) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("Regeneration Shield(s): ").append(regenShields);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Damage Prevention
|
||||||
|
int preventNextDamage = card.getPreventNextDamage();
|
||||||
|
if (preventNextDamage > 0) {
|
||||||
|
str.append("\n");
|
||||||
|
str.append("Prevent the next ").append(preventNextDamage).append(" damage that would be dealt to ");
|
||||||
|
str.append(card.getName()).append(" it this turn.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top revealed
|
||||||
|
if (card.hasKeyword("Play with the top card of your library revealed.") && card.getController() != null
|
||||||
|
&& !card.getController().getZone(Zone.Library).isEmpty()) {
|
||||||
|
str.append("\r\nTop card: ");
|
||||||
|
str.append(card.getController().getCardsIn(Zone.Library, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chosen type
|
||||||
|
if (card.getChosenType() != "") {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("(chosen type: ");
|
||||||
|
str.append(card.getChosenType());
|
||||||
|
str.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chosen color
|
||||||
|
if (!card.getChosenColor().isEmpty()) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("(chosen colors: ");
|
||||||
|
str.append(card.getChosenColor());
|
||||||
|
str.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Named card
|
||||||
|
if (card.getNamedCard() != "") {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("(named card: ");
|
||||||
|
str.append(card.getNamedCard());
|
||||||
|
str.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equipping
|
||||||
|
if (card.getEquipping().size() > 0) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("=Equipping ");
|
||||||
|
str.append(card.getEquipping().get(0));
|
||||||
|
str.append("=");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equipped by
|
||||||
|
if (card.getEquippedBy().size() > 0) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("=Equipped by ");
|
||||||
|
for (Iterator<Card> it = card.getEquippedBy().iterator(); it.hasNext();) {
|
||||||
|
str.append(it.next());
|
||||||
|
if (it.hasNext()) { str.append(", "); }
|
||||||
|
}
|
||||||
|
str.append("=");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enchanting
|
||||||
|
GameEntity entity = card.getEnchanting();
|
||||||
|
if (entity != null) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("*Enchanting ");
|
||||||
|
|
||||||
|
if (entity instanceof Card) {
|
||||||
|
Card temp = (Card) entity;
|
||||||
|
if (temp.isFaceDown() && temp.getController().isComputer()) {
|
||||||
|
str.append("Morph (");
|
||||||
|
str.append(card.getUniqueNumber());
|
||||||
|
str.append(")");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
str.append(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
str.append(entity);
|
||||||
|
}
|
||||||
|
str.append("*");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enchanted by
|
||||||
|
if (card.getEnchantedBy().size() > 0) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("*Enchanted by ");
|
||||||
|
for (Iterator<Card> it = card.getEnchantedBy().iterator(); it.hasNext();) {
|
||||||
|
str.append(it.next());
|
||||||
|
if (it.hasNext()) { str.append(", "); }
|
||||||
|
}
|
||||||
|
str.append("*");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controlling
|
||||||
|
if (card.getGainControlTargets().size() > 0) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("+Controlling: ");
|
||||||
|
for (Iterator<Card> it = card.getGainControlTargets().iterator(); it.hasNext();) {
|
||||||
|
str.append(it.next());
|
||||||
|
if (it.hasNext()) { str.append(", "); }
|
||||||
|
}
|
||||||
|
str.append("+");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cloned via
|
||||||
|
if (card.getCloneOrigin() != null) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("^Cloned via: ");
|
||||||
|
str.append(card.getCloneOrigin().getName());
|
||||||
|
str.append("^");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Imprint
|
||||||
|
if (!card.getImprinted().isEmpty()) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
str.append("^Imprinting: ");
|
||||||
|
for (Iterator<Card> it = card.getImprinted().iterator(); it.hasNext();) {
|
||||||
|
str.append(it.next());
|
||||||
|
if (it.hasNext()) { str.append(", "); }
|
||||||
|
}
|
||||||
|
str.append("^");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uncastable
|
||||||
|
/*if (card.isUnCastable()) {
|
||||||
|
if (str.length() != 0) str.append("\n");
|
||||||
|
str.append("This card can't be cast.");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (card.hasAttachedCardsByMindsDesire()) {
|
||||||
|
if (str.length() != 0) { str.append("\n"); }
|
||||||
|
Card[] cards = card.getAttachedCardsByMindsDesire();
|
||||||
|
str.append("=Attached: ");
|
||||||
|
for (Card temp : cards) {
|
||||||
|
str.append(temp.getName());
|
||||||
|
str.append(" ");
|
||||||
|
}
|
||||||
|
str.append("=");
|
||||||
|
}
|
||||||
|
|
||||||
|
tarInfo.setText(str.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return Card */
|
||||||
|
public Card getCard() {
|
||||||
|
return this.card;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A brief JLabel to consolidate styling. */
|
||||||
|
private class DetailLabel extends JLabel {
|
||||||
|
public DetailLabel(boolean zebra0) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
if (zebra0) {
|
||||||
|
this.setBackground(zebra);
|
||||||
|
this.setOpaque(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setFont(f);
|
||||||
|
this.setForeground(foreground);
|
||||||
|
this.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DetailLabel() {
|
||||||
|
this(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
88
src/main/java/forge/view/toolbox/CardViewer.java
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package forge.view.toolbox;
|
||||||
|
|
||||||
|
import javax.swing.AbstractListModel;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.event.ListSelectionEvent;
|
||||||
|
import javax.swing.event.ListSelectionListener;
|
||||||
|
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.Card;
|
||||||
|
import forge.CardUtil;
|
||||||
|
import forge.gui.game.CardDetailPanel;
|
||||||
|
import forge.gui.game.CardPicturePanel;
|
||||||
|
import forge.item.CardPrinted;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static java.util.Collections.unmodifiableList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple JPanel that shows three columns: card list, pic, and description..
|
||||||
|
*
|
||||||
|
* @author Forge
|
||||||
|
* @version $Id: ListChooser.java 9708 2011-08-09 19:34:12Z jendave $
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class CardViewer extends JPanel {
|
||||||
|
|
||||||
|
//Data and number of choices for the list
|
||||||
|
private List<CardPrinted> list;
|
||||||
|
|
||||||
|
//initialized before; listeners may be added to it
|
||||||
|
private JList jList;
|
||||||
|
private CardDetailPanel detail;
|
||||||
|
private CardPicturePanel picture;
|
||||||
|
|
||||||
|
public CardViewer(List<CardPrinted> list) {
|
||||||
|
this.list = unmodifiableList(list);
|
||||||
|
jList = new JList(new ChooserListModel());
|
||||||
|
detail = new CardDetailPanel(null);
|
||||||
|
picture = new CardPicturePanel(null);
|
||||||
|
|
||||||
|
this.add(new JScrollPane(jList));
|
||||||
|
this.add(picture);
|
||||||
|
this.add(detail);
|
||||||
|
this.setLayout( new java.awt.GridLayout(1, 3, 6, 0) );
|
||||||
|
|
||||||
|
// selection is here
|
||||||
|
jList.getSelectionModel().addListSelectionListener(new SelListener());
|
||||||
|
jList.setSelectedIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ChooserListModel extends AbstractListModel {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 3871965346333840556L;
|
||||||
|
|
||||||
|
public int getSize() { return list.size(); }
|
||||||
|
public Object getElementAt(int index) { return list.get(index); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class SelListener implements ListSelectionListener {
|
||||||
|
private Card[] cache = null;
|
||||||
|
|
||||||
|
public void valueChanged(final ListSelectionEvent e) {
|
||||||
|
int row = jList.getSelectedIndex();
|
||||||
|
// (String) jList.getSelectedValue();
|
||||||
|
if (row >= 0 && row < list.size()) {
|
||||||
|
CardPrinted cp = list.get(row);
|
||||||
|
ensureCacheHas(row, cp);
|
||||||
|
detail.setCard(cache[row]);
|
||||||
|
picture.setCard(cp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureCacheHas(int row, CardPrinted cp) {
|
||||||
|
if (cache == null) { cache = new Card[list.size()]; }
|
||||||
|
if (null == cache[row]) {
|
||||||
|
Card card = AllZone.getCardFactory().getCard(cp.getName(), null);
|
||||||
|
card.setCurSetCode(cp.getSet());
|
||||||
|
card.setImageFilename(CardUtil.buildFilename(card));
|
||||||
|
cache[row] = card;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
78
src/main/java/forge/view/toolbox/FOverlay.java
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package forge.view.toolbox;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semi-transparent overlay panel. Should be used with layered panes.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Currently used only once, in top level UI, with layering already in place.
|
||||||
|
// Getter in AllZone: getOverlay()
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class FOverlay extends JPanel {
|
||||||
|
private JButton btnClose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semi-transparent overlay panel. Should be used with layered panes.
|
||||||
|
*/
|
||||||
|
public FOverlay() {
|
||||||
|
super();
|
||||||
|
btnClose = new JButton("X");
|
||||||
|
btnClose.setForeground(Color.white);
|
||||||
|
btnClose.setBorder(BorderFactory.createLineBorder(Color.white));
|
||||||
|
btnClose.setOpaque(false);
|
||||||
|
btnClose.setBackground(new Color(0, 0, 0));
|
||||||
|
btnClose.setFocusPainted(false);
|
||||||
|
|
||||||
|
btnClose.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
hideOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
public void showOverlay() {
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
public void hideOverlay() {
|
||||||
|
setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the close button, which must be added dynamically since
|
||||||
|
* different overlays have different layouts. The overlay does
|
||||||
|
* not have the close button by default, but a fully working
|
||||||
|
* instance is available if required.
|
||||||
|
*
|
||||||
|
* @return JButton
|
||||||
|
*/
|
||||||
|
public JButton getBtnClose() {
|
||||||
|
return btnClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For some reason, the alpha channel background doesn't work
|
||||||
|
* properly on Windows 7, so the paintComponent override is
|
||||||
|
* required for a semi-transparent overlay.
|
||||||
|
*
|
||||||
|
* @param g   Graphics object
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
g.setColor(new Color(0, 0, 0, 200));
|
||||||
|
g.fillRect(0, 0, getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
190
src/main/java/forge/view/toolbox/FVerticalTabPanel.java
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
package forge.view.toolbox;
|
||||||
|
|
||||||
|
import java.awt.CardLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.border.Border;
|
||||||
|
import javax.swing.border.MatteBorder;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import forge.AllZone;
|
||||||
|
import forge.gui.skin.FPanel;
|
||||||
|
import forge.gui.skin.FSkin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this type.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class FVerticalTabPanel extends FPanel {
|
||||||
|
private CardLayout cards;
|
||||||
|
private JPanel pnlContent;
|
||||||
|
private List<VTab> allVTabs;
|
||||||
|
|
||||||
|
private FSkin skin;
|
||||||
|
private int active;
|
||||||
|
private Color activeColor, inactiveColor, hoverColor;
|
||||||
|
private Border inactiveBorder, hoverBorder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assembles vertical tab panel from list of child panels. Tooltip
|
||||||
|
* on tab is same as tooltip on child panel. Title of tab is same
|
||||||
|
* as name of child panel.
|
||||||
|
*
|
||||||
|
* @param childPanels   JPanels to be placed in tabber
|
||||||
|
*/
|
||||||
|
public FVerticalTabPanel(List<JPanel> childPanels) {
|
||||||
|
// General inits and skin settings
|
||||||
|
super();
|
||||||
|
setLayout(new MigLayout("insets 0, gap 0, wrap 2"));
|
||||||
|
setOpaque(false);
|
||||||
|
int size = childPanels.size();
|
||||||
|
skin = AllZone.getSkin();
|
||||||
|
hoverColor = skin.getClrHover();
|
||||||
|
activeColor = skin.getClrActive();
|
||||||
|
inactiveColor = skin.getClrInactive();
|
||||||
|
hoverBorder = new MatteBorder(1, 0, 1, 1, skin.getClrBorders());
|
||||||
|
inactiveBorder = new MatteBorder(1, 0, 1, 1, new Color(0, 0, 0, 0));
|
||||||
|
|
||||||
|
final int pctTabH = (int) ((100 - 2 - 2) / size);
|
||||||
|
final int pctTabW = 11;
|
||||||
|
final int pctInsetH = 3;
|
||||||
|
final int pctSpacing = 1;
|
||||||
|
|
||||||
|
// Content panel and card layout inits
|
||||||
|
cards = new CardLayout();
|
||||||
|
pnlContent = new JPanel();
|
||||||
|
pnlContent.setOpaque(false);
|
||||||
|
pnlContent.setLayout(cards);
|
||||||
|
pnlContent.setBorder(new MatteBorder(0, 0, 0, 1, skin.getClrBorders()));
|
||||||
|
|
||||||
|
add(pnlContent, "span 1 " + (size + 2) + ", w " + (100 - pctTabW) + "%!, h 100%!");
|
||||||
|
|
||||||
|
JPanel topSpacer = new JPanel();
|
||||||
|
topSpacer.setOpaque(false);
|
||||||
|
add(topSpacer, "w " + pctTabW + "%!, h " + pctInsetH + "%!");
|
||||||
|
|
||||||
|
// Add all tabs
|
||||||
|
VTab tab;
|
||||||
|
allVTabs = new ArrayList<VTab>();
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
tab = new VTab(childPanels.get(i).getName(), i);
|
||||||
|
tab.setToolTipText(childPanels.get(i).getToolTipText());
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
tab.setBackground(activeColor);
|
||||||
|
active = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tab.setBackground(inactiveColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
add(tab, "w " + pctTabW + "%!, h " + (pctTabH - pctSpacing) + "%!, gapbottom " + pctSpacing + "%!");
|
||||||
|
allVTabs.add(tab);
|
||||||
|
|
||||||
|
// Add card to content panel
|
||||||
|
pnlContent.add(childPanels.get(i), "CARD" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
JPanel bottomSpacer = new JPanel();
|
||||||
|
bottomSpacer.setOpaque(false);
|
||||||
|
add(bottomSpacer, "w 10%!, h " + (pctInsetH + pctSpacing) + "%!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Programatically flips tab layout to specified number (without needing
|
||||||
|
* a mouse event).
|
||||||
|
*
|
||||||
|
* @param index   Tab number, starting from 0
|
||||||
|
*/
|
||||||
|
public void showTab(int index) {
|
||||||
|
if (index >= this.allVTabs.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
allVTabs.get(active).setBackground(inactiveColor);
|
||||||
|
active = index;
|
||||||
|
cards.show(pnlContent, "CARD" + index);
|
||||||
|
allVTabs.get(active).setBackground(activeColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return JPanel */
|
||||||
|
public JPanel getContentPanel() {
|
||||||
|
return pnlContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single instance of a vertical tab, with paintComponent overridden
|
||||||
|
* to provide vertical-ness. Also manages root level hover and click effects.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class VTab extends JPanel {
|
||||||
|
private String msg;
|
||||||
|
private int id, w;
|
||||||
|
|
||||||
|
// ID is used to retrieve this tab from the list of allVTabs.
|
||||||
|
VTab(String txt, int i) {
|
||||||
|
super();
|
||||||
|
setLayout(new MigLayout("insets 0, gap 0"));
|
||||||
|
setOpaque(true);
|
||||||
|
msg = txt;
|
||||||
|
id = i;
|
||||||
|
|
||||||
|
addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
if (id != active) {
|
||||||
|
setBorder(hoverBorder);
|
||||||
|
setBackground(hoverColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
if (id != active) {
|
||||||
|
setBorder(inactiveBorder);
|
||||||
|
setBackground(inactiveColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
allVTabs.get(active).setBackground(inactiveColor);
|
||||||
|
active = id;
|
||||||
|
cards.show(pnlContent, "CARD" + id);
|
||||||
|
setBackground(activeColor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
w = getWidth();
|
||||||
|
|
||||||
|
// Careful with this font scale factor; the vertical tabs will be unreadable
|
||||||
|
// if small window, too big if large window.
|
||||||
|
g.setFont(skin.getFont1().deriveFont(Font.PLAIN, (int) (w * 0.68)));
|
||||||
|
|
||||||
|
// Rotate, draw string, rotate back (to allow hover border to be painted properly)
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
AffineTransform at = g2d.getTransform();
|
||||||
|
at.rotate(Math.toRadians(90), 0, 0);
|
||||||
|
g2d.setTransform(at);
|
||||||
|
g2d.setColor(AllZone.getSkin().getClrText());
|
||||||
|
g2d.drawString(msg, 5, -4);
|
||||||
|
|
||||||
|
at.rotate(Math.toRadians(-90), 0, 0);
|
||||||
|
g2d.setTransform(at);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||