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_white_n.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/btnLdown.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/font2.ttf -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/texture2.jpg -text
|
||||
res/images/skins/default/texture3.jpg -text
|
||||
res/images/skins/rebel/bg_match.jpg -text
|
||||
res/images/skins/rebel/bg_splash.jpg -text
|
||||
res/images/skins/rebel/btnLdown.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/font2.ttf -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/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/1.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/countersMulti.png -text
|
||||
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/foil02.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/TriggerUntaps.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/DeckGeneration.java -text
|
||||
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/package-info.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/swing/ApplicationView.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/WinLoseModeHandler.java -text
|
||||
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/util/ClumsyRunnable.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/reprintSetInfo.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/matchOLD
|
||||
src/main/java/forge/gui/toolbox
|
||||
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
|
||||
/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/opponent=Gegner
|
||||
NewGame/deckeditor=Deck Editor
|
||||
NewGame/newgui=New Gui
|
||||
NewGame/oldgui=Old Gui
|
||||
NewGame/ailand=Stack AI Land
|
||||
NewGame/devmode=Developer Mode
|
||||
NewGame/questmode=Quest Mode
|
||||
@@ -142,7 +142,7 @@ NewGame/startgame=Spiel starten
|
||||
NewGame/savesealed_msg=Please name this sealed deck
|
||||
NewGame/savesealed_ttl=Save Sealed Deck
|
||||
|
||||
WinLose/won=Siege:
|
||||
WinLose/won=Siege:
|
||||
WinLose/lost=, Niederlagen:
|
||||
WinLose/win=Gewonnen
|
||||
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/opponent=Opponent
|
||||
NewGame/deckeditor=Deck Editor
|
||||
NewGame/newgui=New Gui
|
||||
NewGame/oldgui=Old Gui
|
||||
NewGame/ailand=Stack AI Land
|
||||
NewGame/devmode=Developer Mode
|
||||
NewGame/questmode=Quest Mode
|
||||
|
||||
@@ -11,6 +11,7 @@ import forge.card.trigger.TriggerHandler;
|
||||
import forge.deck.DeckManager;
|
||||
import forge.game.GameSummary;
|
||||
import forge.gui.input.InputControl;
|
||||
import forge.view.toolbox.FOverlay;
|
||||
import forge.gui.skin.FSkin;
|
||||
import forge.model.FGameState;
|
||||
import forge.properties.ForgeProps;
|
||||
@@ -78,6 +79,9 @@ public final class AllZone {
|
||||
/** Global <code>display</code>. */
|
||||
private static Display display;
|
||||
|
||||
/** Global <code>overlay</code>. */
|
||||
private static FOverlay overlay;
|
||||
|
||||
/** Constant <code>DECK_MGR</code>. */
|
||||
private static DeckManager deckManager;
|
||||
|
||||
@@ -629,4 +633,18 @@ public final class AllZone {
|
||||
public static void setSkin(final FSkin fs) {
|
||||
skin = fs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return overlay
|
||||
*/
|
||||
public static FOverlay getOverlay() {
|
||||
return overlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param overlay0   Overlay panel
|
||||
*/
|
||||
public static void setOverlay(FOverlay overlay0) {
|
||||
overlay = overlay0;
|
||||
}
|
||||
} // AllZone
|
||||
|
||||
@@ -40,10 +40,17 @@ public final class Constant {
|
||||
public static final boolean[] MILL = new boolean[1];
|
||||
|
||||
/** The Constant DevMode. */
|
||||
public static final boolean[] DEV_MODE = new boolean[1]; // one for
|
||||
// normal mode
|
||||
// one for quest
|
||||
// mode
|
||||
// one for normal mode, one for quest mode
|
||||
public static final boolean[] DEV_MODE = new boolean[1];
|
||||
|
||||
/** 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. */
|
||||
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.quest.gui.QuestWinLoseHandler;
|
||||
import forge.quest.gui.main.QuestEvent;
|
||||
import forge.view.match.ViewTopLevel;
|
||||
import forge.view.swing.WinLoseFrame;
|
||||
|
||||
/**
|
||||
@@ -776,14 +777,22 @@ public class GameAction {
|
||||
final boolean refreeze = AllZone.getStack().isFrozen();
|
||||
AllZone.getStack().setFrozen(true);
|
||||
|
||||
final JFrame frame = (JFrame) AllZone.getDisplay();
|
||||
if (!frame.isDisplayable()) {
|
||||
return;
|
||||
if (Constant.Runtime.OLDGUI[0]) {
|
||||
final JFrame frame = (JFrame) AllZone.getDisplay();
|
||||
if (!frame.isDisplayable()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
final ViewTopLevel frame = (ViewTopLevel) AllZone.getDisplay();
|
||||
if (!frame.isDisplayable()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.canShowWinLose && this.checkEndGameSate()) {
|
||||
AllZone.getDisplay().savePrefs();
|
||||
frame.setEnabled(false);
|
||||
//frame.setEnabled(false);
|
||||
// frame.dispose();
|
||||
|
||||
// Gui_WinLose gwl = new Gui_WinLose(AllZone.getMatchState(),
|
||||
|
||||
@@ -516,6 +516,9 @@ public class Phase extends MyObservable implements java.io.Serializable {
|
||||
this.turn++;
|
||||
}
|
||||
|
||||
// Visual indicators
|
||||
PhaseUtil.visuallyActivatePhase(this.getPhase());
|
||||
|
||||
// When consecutively skipping phases (like in combat) this section
|
||||
// pushes through that block
|
||||
this.updateObservers();
|
||||
|
||||
@@ -6,6 +6,8 @@ import java.util.HashMap;
|
||||
import forge.Constant.Zone;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.gui.input.Input;
|
||||
import forge.view.match.ViewField.PhaseLabel;
|
||||
import forge.view.match.ViewTopLevel;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -423,6 +425,7 @@ public class PhaseUtil {
|
||||
*/
|
||||
public static void handleUpkeep() {
|
||||
Player turn = AllZone.getPhase().getPlayerTurn();
|
||||
|
||||
if (skipUpkeep()) {
|
||||
// Slowtrips all say "on the next turn's upkeep" if there is no
|
||||
// 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.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);
|
||||
|
||||
/**
|
||||
* Instantiates a new f button.
|
||||
* Instantiates a new FButton.
|
||||
*/
|
||||
public FButton() {
|
||||
this("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new FButton.
|
||||
*
|
||||
* @param msg
|
||||
* the msg
|
||||
|
||||
@@ -2,6 +2,7 @@ package forge.gui.skin;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.LayoutManager;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
@@ -11,14 +12,15 @@ import javax.swing.JPanel;
|
||||
* <p>
|
||||
* FPanel.
|
||||
* </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")
|
||||
public class FPanel extends JPanel {
|
||||
private ImageIcon bgImg = null;
|
||||
private int w, h, iw, ih, x, y = 0;
|
||||
private Image bgTexture, bgImg = null;
|
||||
// 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.
|
||||
@@ -45,40 +47,84 @@ public class FPanel extends JPanel {
|
||||
*/
|
||||
@Override
|
||||
protected void paintComponent(final Graphics g) {
|
||||
// System.out.print("\nRepainting. ");
|
||||
if (this.bgImg != null) {
|
||||
this.w = this.getWidth();
|
||||
this.h = this.getHeight();
|
||||
this.iw = this.bgImg.getIconWidth();
|
||||
this.ih = this.bgImg.getIconHeight();
|
||||
w = this.getWidth();
|
||||
h = this.getHeight();
|
||||
|
||||
while (this.x < this.w) {
|
||||
while (this.y < this.h) {
|
||||
g.drawImage(this.bgImg.getImage(), this.x, this.y, null);
|
||||
this.y += this.ih;
|
||||
// Draw background texture
|
||||
if (bgTexture != null) {
|
||||
iw = bgTexture.getWidth(null);
|
||||
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;
|
||||
this.y = 0;
|
||||
x += iw;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bG img.
|
||||
*
|
||||
* @param icon
|
||||
* the new 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
|
||||
* texture, centered and scaled proportional to its aspect ratio.
|
||||
*
|
||||
* @param i0   ImageIcon
|
||||
*/
|
||||
public void setBGImg(final ImageIcon icon) {
|
||||
this.bgImg = icon;
|
||||
public void setBGImg(final ImageIcon i0) {
|
||||
this.bgImg = i0.getImage();
|
||||
if (this.bgImg != null) {
|
||||
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.
|
||||
*
|
||||
|
||||
@@ -22,6 +22,7 @@ import forge.AllZone;
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class FRoundedPanel extends JPanel {
|
||||
private boolean[] borders = { true, true, true, true };
|
||||
private boolean[] corners = { true, true, true, true }; // NW, SW, SE, NE
|
||||
private Color shadowColor = new Color(150, 150, 150, 150);
|
||||
private Color borderColor = AllZone.getSkin().getClrBorders();
|
||||
@@ -146,39 +147,56 @@ public class FRoundedPanel extends JPanel {
|
||||
|
||||
// Mid, left, right rectangles: border
|
||||
g2d.setColor(this.borderColor);
|
||||
g2d.drawLine(r, 0, w - r - so, 0);
|
||||
g2d.drawLine(r, h - so - 1, w - r - so, h - so - 1);
|
||||
g2d.drawLine(0, r, 0, h - r - so);
|
||||
g2d.drawLine(w - so - 1, r, w - so - 1, h - r - so);
|
||||
|
||||
if (this.borders[0]) { g2d.drawLine(r, 0, w - r - so, 0); }
|
||||
if (this.borders[1]) { g2d.drawLine(0, r, 0, 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
|
||||
// NW
|
||||
if (this.corners[0]) {
|
||||
g2d.drawArc(0, 0, 2 * r, 2 * r, 90, 90);
|
||||
} else {
|
||||
g2d.drawLine(0, 0, r, 0);
|
||||
g2d.drawLine(0, 0, 0, r);
|
||||
if (this.borders[0]) {
|
||||
g2d.drawLine(0, 0, r, 0);
|
||||
}
|
||||
if (this.borders[1]) {
|
||||
g2d.drawLine(0, 0, 0, r);
|
||||
}
|
||||
}
|
||||
// SW
|
||||
if (this.corners[1]) {
|
||||
g2d.drawArc(0, h - (2 * r) - so, 2 * r, (2 * r) - 1, 180, 90);
|
||||
} else {
|
||||
g2d.drawLine(0, h - so - 1, 0, h - r - so - 1);
|
||||
g2d.drawLine(0, h - so - 1, r, h - so - 1);
|
||||
if (this.borders[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
|
||||
if (this.corners[2]) {
|
||||
g2d.drawArc(w - (2 * r) - so, h - (2 * r) - so, (2 * r) - 1, (2 * r) - 1, 270, 90);
|
||||
} else {
|
||||
g2d.drawLine(w - so - 1, h - so - 1, w - so - 1, h - r - so);
|
||||
g2d.drawLine(w - so - 1, h - so - 1, w - r - so, h - so - 1);
|
||||
if (this.borders[2]) {
|
||||
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
|
||||
if (this.corners[3]) {
|
||||
g2d.drawArc(w - (2 * r) - so, 0, (2 * r) - 1, (2 * r) - 1, 0, 90);
|
||||
} else {
|
||||
g2d.drawLine(w - so - 1, 0, w - so - r, 0);
|
||||
g2d.drawLine(w - so - 1, 0, w - so - 1, r);
|
||||
if (this.borders[0]) {
|
||||
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>
|
||||
* Sets radius of each corner on rounded panel.
|
||||
*
|
||||
* @param r
|
||||
* the new corner radius
|
||||
* @param r0   int
|
||||
*/
|
||||
public void setCornerRadius(int r) {
|
||||
if (r < 0) {
|
||||
r = 0;
|
||||
public void setCornerRadius(int r0) {
|
||||
if (r0 < 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,
|
||||
* SE, NE
|
||||
*
|
||||
* @param vals
|
||||
* the new corners
|
||||
* @param vals   boolean[4]
|
||||
*/
|
||||
public void setCorners(final boolean[] vals) {
|
||||
if (vals.length != 4) {
|
||||
@@ -259,6 +275,23 @@ public class FRoundedPanel extends JPanel {
|
||||
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.
|
||||
*
|
||||
|
||||
@@ -28,6 +28,9 @@ public class FSkin {
|
||||
/** Primary texture used in skin. */
|
||||
private ImageIcon texture1 = null;
|
||||
|
||||
/** Primary background image used during match play. */
|
||||
private ImageIcon matchBG = null;
|
||||
|
||||
/** Left side of button, up state. */
|
||||
private ImageIcon btnLup = null;
|
||||
|
||||
@@ -58,6 +61,17 @@ public class FSkin {
|
||||
/** Splash screen image. */
|
||||
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. */
|
||||
private Color clrTheme = Color.red;
|
||||
|
||||
@@ -95,7 +109,7 @@ public class FSkin {
|
||||
private String name = "default";
|
||||
|
||||
// ===== Private fields
|
||||
private final String paletteFile = "palette.png";
|
||||
private final String spriteFile = "sprite.png";
|
||||
private final String font1file = "font1.ttf";
|
||||
private final String font2file = "font2.ttf";
|
||||
private final String texture1file = "texture1.jpg";
|
||||
@@ -109,11 +123,11 @@ public class FSkin {
|
||||
private final String btnMdownfile = "btnMdown.png";
|
||||
private final String btnRdownfile = "btnRdown.png";
|
||||
private final String splashfile = "bg_splash.jpg";
|
||||
private final String matchfile = "bg_match.jpg";
|
||||
|
||||
private ImageIcon tempImg;
|
||||
private Font tempFont;
|
||||
private String skin;
|
||||
private final String notfound = "FSkin.java: \"" + this.skin + "\" skin can't find ";
|
||||
private final String notfound = "FSkin.java: Can't find ";
|
||||
|
||||
/**
|
||||
* FSkin constructor. No arguments, will generate default skin settings,
|
||||
@@ -153,6 +167,7 @@ public class FSkin {
|
||||
|
||||
// Images
|
||||
this.setTexture1(this.retrieveImage(dirName + this.texture1file));
|
||||
this.setMatchBG(this.retrieveImage(dirName + this.matchfile));
|
||||
this.setBtnLup(this.retrieveImage(dirName + this.btnLupfile));
|
||||
this.setBtnMup(this.retrieveImage(dirName + this.btnMupfile));
|
||||
this.setBtnRup(this.retrieveImage(dirName + this.btnRupfile));
|
||||
@@ -162,26 +177,35 @@ public class FSkin {
|
||||
this.setBtnLdown(this.retrieveImage(dirName + this.btnLdownfile));
|
||||
this.setBtnMdown(this.retrieveImage(dirName + this.btnMdownfile));
|
||||
this.setBtnRdown(this.retrieveImage(dirName + this.btnRdownfile));
|
||||
this.setSplash(this.retrieveImage(dirName + this.splashfile));
|
||||
this.setSplashBG(this.retrieveImage(dirName + this.splashfile));
|
||||
|
||||
// Color palette
|
||||
final File file = new File(dirName + this.paletteFile);
|
||||
final File file = new File(dirName + this.spriteFile);
|
||||
BufferedImage image;
|
||||
try {
|
||||
image = ImageIO.read(file);
|
||||
this.setClrTheme(this.getColorFromPixel(image.getRGB(60, 10)));
|
||||
this.setClrBorders(this.getColorFromPixel(image.getRGB(60, 30)));
|
||||
this.setClrZebra(this.getColorFromPixel(image.getRGB(60, 50)));
|
||||
this.setClrHover(this.getColorFromPixel(image.getRGB(60, 70)));
|
||||
this.setClrActive(this.getColorFromPixel(image.getRGB(60, 90)));
|
||||
this.setClrInactive(this.getColorFromPixel(image.getRGB(60, 110)));
|
||||
this.setClrText(this.getColorFromPixel(image.getRGB(60, 130)));
|
||||
this.setClrProgress1(this.getColorFromPixel(image.getRGB(55, 145)));
|
||||
this.setClrProgress2(this.getColorFromPixel(image.getRGB(65, 145)));
|
||||
this.setClrProgress3(this.getColorFromPixel(image.getRGB(55, 155)));
|
||||
this.setClrProgress4(this.getColorFromPixel(image.getRGB(65, 155)));
|
||||
this.setClrTheme(this.getColorFromPixel(image.getRGB(70, 10)));
|
||||
this.setClrBorders(this.getColorFromPixel(image.getRGB(70, 30)));
|
||||
this.setClrZebra(this.getColorFromPixel(image.getRGB(70, 50)));
|
||||
this.setClrHover(this.getColorFromPixel(image.getRGB(70, 70)));
|
||||
this.setClrActive(this.getColorFromPixel(image.getRGB(70, 90)));
|
||||
this.setClrInactive(this.getColorFromPixel(image.getRGB(70, 110)));
|
||||
this.setClrText(this.getColorFromPixel(image.getRGB(70, 130)));
|
||||
this.setClrProgress1(this.getColorFromPixel(image.getRGB(65, 145)));
|
||||
this.setClrProgress2(this.getColorFromPixel(image.getRGB(75, 145)));
|
||||
this.setClrProgress3(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) {
|
||||
System.err.println(this.notfound + this.paletteFile);
|
||||
System.err.println(this.notfound + this.spriteFile);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -273,7 +297,7 @@ public class FSkin {
|
||||
* Splash screen image.
|
||||
* @return {@link javax.swing.ImageIcon} splash
|
||||
*/
|
||||
public ImageIcon getSplash() {
|
||||
public ImageIcon getSplashBG() {
|
||||
return splash;
|
||||
}
|
||||
|
||||
@@ -281,7 +305,7 @@ public class FSkin {
|
||||
* Splash screen image.
|
||||
* @param splash0   an image icon
|
||||
*/
|
||||
public void setSplash(ImageIcon splash0) {
|
||||
public void setSplashBG(ImageIcon splash0) {
|
||||
this.splash = splash0;
|
||||
}
|
||||
|
||||
@@ -333,6 +357,22 @@ public class FSkin {
|
||||
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.
|
||||
* @return {@link java.awt.Color} clrZebra
|
||||
@@ -626,4 +666,94 @@ public class FSkin {
|
||||
public String getName() {
|
||||
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
|
||||
*/
|
||||
protected final void setPhase(final Phase phase0) {
|
||||
System.out.println("asdf:"+phase0);
|
||||
this.phase = phase0;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ import java.util.List;
|
||||
*/
|
||||
public class ForgePreferences extends Preferences {
|
||||
|
||||
/** The new gui. */
|
||||
private final boolean newGui;
|
||||
/** Old gui checkbox toggle. */
|
||||
private boolean oldGui;
|
||||
|
||||
/** The stack ai land. */
|
||||
private boolean stackAiLand;
|
||||
@@ -27,7 +27,13 @@ public class ForgePreferences extends Preferences {
|
||||
/** The milling loss condition. */
|
||||
private boolean millingLossCondition;
|
||||
|
||||
/** The developer mode. */
|
||||
/** Hand view toggle. */
|
||||
private boolean handView;
|
||||
|
||||
/** Library view toggle. */
|
||||
private boolean libraryView;
|
||||
|
||||
/** Developer mode. */
|
||||
private boolean developerMode;
|
||||
|
||||
/** The upload draft ai. */
|
||||
@@ -106,6 +112,17 @@ public class ForgePreferences extends Preferences {
|
||||
/** The b human end combat. */
|
||||
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 String fileName;
|
||||
|
||||
@@ -135,9 +152,11 @@ public class ForgePreferences extends Preferences {
|
||||
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.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.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.setbHumanBeginCombat(this.getBoolean("phase.human.beginCombat", 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 {
|
||||
|
||||
this.set("gui.new", this.newGui);
|
||||
this.set("gui.old", this.oldGui);
|
||||
|
||||
this.set("AI.stack.land", this.isStackAiLand());
|
||||
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("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.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 {
|
||||
final FileOutputStream stream = new FileOutputStream(this.fileName);
|
||||
this.store(stream, "Forge");
|
||||
@@ -248,7 +289,7 @@ public class ForgePreferences extends Preferences {
|
||||
/**
|
||||
* Checks if is stack ai land.
|
||||
*
|
||||
* @return the stackAiLand
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isStackAiLand() {
|
||||
return this.stackAiLand;
|
||||
@@ -257,29 +298,78 @@ public class ForgePreferences extends Preferences {
|
||||
/**
|
||||
* Sets the stack ai land.
|
||||
*
|
||||
* @param stackAiLand the stackAiLand to set
|
||||
* @param b0   boolean
|
||||
*/
|
||||
public void setStackAiLand(final boolean stackAiLand) {
|
||||
this.stackAiLand = stackAiLand; // TODO: Add 0 to parameter's name.
|
||||
public void setStackAiLand(final boolean b0) {
|
||||
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() {
|
||||
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) {
|
||||
this.millingLossCondition = millingLossCondition; // TODO: Add 0 to
|
||||
// parameter's name.
|
||||
public void setMillingLossCondition(final boolean millingLossCondition0) {
|
||||
this.millingLossCondition = millingLossCondition0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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. */
|
||||
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";
|
||||
|
||||
/** 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. */
|
||||
public static final String AI_LAND = "%s/NewGame/ailand";
|
||||
|
||||
@@ -31,6 +31,7 @@ import forge.Command;
|
||||
import forge.Constant;
|
||||
import forge.GuiDisplay;
|
||||
import forge.ImageCache;
|
||||
import forge.control.ControlAllUI;
|
||||
import forge.deck.Deck;
|
||||
import forge.gui.GuiUtils;
|
||||
import forge.gui.deckeditor.DeckEditorQuest;
|
||||
@@ -755,13 +756,14 @@ public class QuestMainPanel extends QuestAbstractPanel {
|
||||
// Dev Mode occurs before Display
|
||||
Constant.Runtime.DEV_MODE[0] = this.devModeCheckBox.isSelected();
|
||||
|
||||
// DO NOT CHANGE THIS ORDER, GuiDisplay needs to be created before cards
|
||||
// are added
|
||||
// if (newGUICheckbox.isSelected()) {
|
||||
AllZone.setDisplay(new GuiDisplay());
|
||||
// } else {
|
||||
// AllZone.setDisplay(new GuiDisplay3());
|
||||
// }
|
||||
if (Constant.Runtime.OLDGUI[0]) {
|
||||
AllZone.setDisplay(new GuiDisplay());
|
||||
}
|
||||
else {
|
||||
ControlAllUI ui = new ControlAllUI();
|
||||
AllZone.setDisplay(ui.getMatchView());
|
||||
ui.getMatchController().initMatch();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
OldGuiNewGame.getUseLAFFonts().setSelected(preferences.isLafFonts());
|
||||
// newGuiCheckBox.setSelected(preferences.newGui);
|
||||
OldGuiNewGame.getOldGuiCheckBox().setSelected(preferences.isOldGui());
|
||||
OldGuiNewGame.getSmoothLandCheckBox().setSelected(preferences.isStackAiLand());
|
||||
OldGuiNewGame.getDevModeCheckBox().setSelected(preferences.isDeveloperMode());
|
||||
OldGuiNewGame.getCardOverlay().setSelected(preferences.isCardOverlay());
|
||||
|
||||
@@ -59,6 +59,7 @@ import forge.ImageCache;
|
||||
import forge.MyRandom;
|
||||
import forge.PlayerType;
|
||||
import forge.Singletons;
|
||||
import forge.control.ControlAllUI;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGeneration;
|
||||
import forge.deck.DeckManager;
|
||||
@@ -124,8 +125,8 @@ public class OldGuiNewGame extends JFrame {
|
||||
|
||||
// @SuppressWarnings("unused")
|
||||
// titledBorder2
|
||||
/** Constant <code>newGuiCheckBox</code>. */
|
||||
// private static JCheckBox newGuiCheckBox = new JCheckBox("", true);
|
||||
/** Constant <code>oldGuiCheckBox</code>. */
|
||||
private static JCheckBox oldGuiCheckBox = new JCheckBox("", false);
|
||||
/** Constant <code>smoothLandCheckBox</code>. */
|
||||
private static JCheckBox smoothLandCheckBox = new JCheckBox("", false);
|
||||
/** Constant <code>devModeCheckBox</code>. */
|
||||
@@ -556,7 +557,7 @@ public class OldGuiNewGame extends JFrame {
|
||||
ForgeProps.getLocalized(NewConstants.Lang.OldGuiNewGame.NewGameText.SETTINGS));
|
||||
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(
|
||||
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");
|
||||
|
||||
// jPanel3.add(newGuiCheckBox, "wrap");
|
||||
jPanel3.add(oldGuiCheckBox, "wrap");
|
||||
this.jPanel3.add(OldGuiNewGame.getSmoothLandCheckBox(), "wrap");
|
||||
this.jPanel3.add(OldGuiNewGame.getDevModeCheckBox(), "wrap");
|
||||
this.jPanel3.add(OldGuiNewGame.getUpldDrftCheckBox(), "wrap");
|
||||
@@ -865,15 +866,19 @@ public class OldGuiNewGame extends JFrame {
|
||||
}
|
||||
} // else
|
||||
|
||||
// DO NOT CHANGE THIS ORDER, GuiDisplay needs to be created before cards
|
||||
// are added
|
||||
// Constant.Runtime.DevMode[0] = devModeCheckBox.isSelected();
|
||||
Constant.Runtime.OLDGUI[0] = oldGuiCheckBox.isSelected();
|
||||
|
||||
// if (newGuiCheckBox.isSelected())
|
||||
AllZone.setDisplay(new GuiDisplay());
|
||||
// else AllZone.setDisplay(new GuiDisplay3());
|
||||
if (Constant.Runtime.OLDGUI[0]) {
|
||||
AllZone.setDisplay(new GuiDisplay());
|
||||
}
|
||||
else {
|
||||
ControlAllUI ui = new ControlAllUI();
|
||||
AllZone.setDisplay(ui.getMatchView());
|
||||
ui.getMatchController().initMatch();
|
||||
}
|
||||
|
||||
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.getDisplay().setVisible(true);
|
||||
@@ -1714,7 +1719,7 @@ public class OldGuiNewGame extends JFrame {
|
||||
final ForgePreferences preferences = Singletons.getModel().getPreferences();
|
||||
preferences.setLaf(UIManager.getLookAndFeel().getClass().getName());
|
||||
preferences.setLafFonts(OldGuiNewGame.getUseLAFFonts().isSelected());
|
||||
// preferences.newGui = newGuiCheckBox.isSelected();
|
||||
preferences.setOldGui(oldGuiCheckBox.isSelected());
|
||||
preferences.setStackAiLand(OldGuiNewGame.getSmoothLandCheckBox().isSelected());
|
||||
preferences.setMillingLossCondition(Constant.Runtime.MILL[0]);
|
||||
preferences.setDeveloperMode(Constant.Runtime.DEV_MODE[0]);
|
||||
@@ -2000,4 +2005,8 @@ public class OldGuiNewGame extends JFrame {
|
||||
// name.
|
||||
}
|
||||
|
||||
/** @return JCheckBox */
|
||||
public static JCheckBox getOldGuiCheckBox() {
|
||||
return OldGuiNewGame.oldGuiCheckBox;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SplashFrame extends JFrame {
|
||||
this.setUndecorated(true);
|
||||
|
||||
// Set preferred JFrame properties.
|
||||
final ImageIcon bgIcon = skin.getSplash();
|
||||
final ImageIcon bgIcon = skin.getSplashBG();
|
||||
final int splashWidthPx = bgIcon.getIconWidth();
|
||||
final int splashHeightPx = bgIcon.getIconHeight();
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import javax.swing.border.AbstractBorder;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.AllZone;
|
||||
import forge.Constant;
|
||||
import forge.Phase;
|
||||
import forge.Player;
|
||||
import forge.gui.skin.FButton;
|
||||
@@ -24,6 +25,7 @@ import forge.gui.skin.FPanel;
|
||||
import forge.properties.ForgeProps;
|
||||
import forge.properties.NewConstants.Lang.WinLoseFrame.WinLoseText;
|
||||
import forge.quest.data.QuestMatchState;
|
||||
import forge.view.match.ViewTopLevel;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -88,7 +90,7 @@ public class WinLoseFrame extends JFrame {
|
||||
|
||||
// Place all content in FPanel
|
||||
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());
|
||||
this.getContentPane().add(contentPanel);
|
||||
|
||||
@@ -271,8 +273,17 @@ public class WinLoseFrame extends JFrame {
|
||||
* @return {@link javax.swing.JFrame} display frame
|
||||
*/
|
||||
final JFrame closeWinLoseFrame() {
|
||||
JFrame frame;
|
||||
|
||||
// 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.setEnabled(true);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||