- ComboBox style now set globally via UIManager which should hopefully resolve issue with Mac (see http://www.slightlymagic.net/forum/viewtopic.php?f=52&t=11126#p125845).

This commit is contained in:
spr
2013-08-16 19:45:42 +00:00
parent ce988a66df
commit ef8bb689d7
2 changed files with 466 additions and 451 deletions

View File

@@ -1,272 +1,289 @@
/* /*
* Forge: Play Magic: the Gathering. * Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team * Copyright (C) 2011 Forge Team
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package forge.control; package forge.control;
import java.awt.Component; import java.awt.Component;
import java.awt.event.ComponentAdapter; import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.awt.event.WindowListener; import java.awt.event.WindowListener;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JLayeredPane; import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.WindowConstants; import javax.swing.WindowConstants;
import forge.Card; import forge.Card;
import forge.Constant.Preferences; import forge.Constant.Preferences;
import forge.Singletons; import forge.Singletons;
import forge.control.KeyboardShortcuts.Shortcut; import forge.control.KeyboardShortcuts.Shortcut;
import forge.game.Game; import forge.game.Game;
import forge.game.GameType; import forge.game.GameType;
import forge.game.Match; import forge.game.Match;
import forge.game.player.LobbyPlayer; import forge.game.player.LobbyPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.gui.GuiDialog; import forge.gui.GuiDialog;
import forge.gui.SOverlayUtils; import forge.gui.SOverlayUtils;
import forge.gui.deckeditor.CDeckEditorUI; import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.deckeditor.VDeckEditorUI; import forge.gui.deckeditor.VDeckEditorUI;
import forge.gui.framework.EDocID; import forge.gui.framework.EDocID;
import forge.gui.framework.InvalidLayoutFileException; import forge.gui.framework.InvalidLayoutFileException;
import forge.gui.framework.SDisplayUtil; import forge.gui.framework.SDisplayUtil;
import forge.gui.framework.SLayoutIO; import forge.gui.framework.SLayoutIO;
import forge.gui.framework.SOverflowUtil; import forge.gui.framework.SOverflowUtil;
import forge.gui.framework.SResizingUtil; import forge.gui.framework.SResizingUtil;
import forge.gui.home.CHomeUI; import forge.gui.home.CHomeUI;
import forge.gui.home.VHomeUI; import forge.gui.home.VHomeUI;
import forge.gui.match.CMatchUI; import forge.gui.match.CMatchUI;
import forge.gui.match.VMatchUI; import forge.gui.match.VMatchUI;
import forge.gui.match.controllers.CDock; import forge.gui.match.controllers.CDock;
import forge.gui.match.controllers.CLog; import forge.gui.match.controllers.CLog;
import forge.gui.match.controllers.CMessage; import forge.gui.match.controllers.CMessage;
import forge.gui.match.controllers.CStack; import forge.gui.match.controllers.CStack;
import forge.gui.match.nonsingleton.VField; import forge.gui.match.nonsingleton.VField;
import forge.gui.match.views.VAntes; import forge.gui.match.views.VAntes;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.net.FServer; import forge.net.FServer;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.properties.NewConstants; import forge.properties.NewConstants;
import forge.quest.QuestController; import forge.quest.QuestController;
import forge.quest.data.QuestPreferences.QPref; import forge.quest.data.QuestPreferences.QPref;
import forge.quest.io.QuestDataIO; import forge.quest.io.QuestDataIO;
import forge.sound.SoundSystem; import forge.sound.SoundSystem;
import forge.view.FView; import forge.view.FView;
/** /**
* <p> * <p>
* FControl. * FControl.
* </p> * </p>
* Controls all Forge UI functionality inside one JFrame. This class switches * Controls all Forge UI functionality inside one JFrame. This class switches
* between various display states in that JFrame. Controllers are instantiated * between various display states in that JFrame. Controllers are instantiated
* separately by each state's top level view class. * separately by each state's top level view class.
*/ */
public enum FControl { public enum FControl {
instance; instance;
private List<Shortcut> shortcuts; private List<Shortcut> shortcuts;
private JLayeredPane display; private JLayeredPane display;
private Screens state = Screens.UNKNOWN; private Screens state = Screens.UNKNOWN;
private WindowListener waDefault, waConcede, waLeaveBazaar, waLeaveEditor; private WindowListener waDefault, waConcede, waLeaveBazaar, waLeaveEditor;
public static enum Screens { public static enum Screens {
UNKNOWN, UNKNOWN,
HOME_SCREEN, HOME_SCREEN,
MATCH_SCREEN, MATCH_SCREEN,
DECK_EDITOR_CONSTRUCTED, DECK_EDITOR_CONSTRUCTED,
QUEST_BAZAAR, QUEST_BAZAAR,
DECK_EDITOR_LIMITED, DECK_EDITOR_LIMITED,
DECK_EDITOR_QUEST, DECK_EDITOR_QUEST,
QUEST_CARD_SHOP, QUEST_CARD_SHOP,
DRAFTING_PROCESS DRAFTING_PROCESS
} }
private final SoundSystem soundSystem = new SoundSystem(); private final SoundSystem soundSystem = new SoundSystem();
/** /**
* <p> * <p>
* FControl. * FControl.
* </p> * </p>
* Controls all Forge UI functionality inside one JFrame. This class * Controls all Forge UI functionality inside one JFrame. This class
* switches between various display states in that JFrame. Controllers are * switches between various display states in that JFrame. Controllers are
* instantiated separately by each state's top level view class. * instantiated separately by each state's top level view class.
*/ */
private FControl() { private FControl() {
this.waDefault = new WindowAdapter() { this.waDefault = new WindowAdapter() {
@Override @Override
public void windowClosing(final WindowEvent e) { public void windowClosing(final WindowEvent e) {
Singletons.getView().getFrame().setDefaultCloseOperation( Singletons.getView().getFrame().setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE); WindowConstants.EXIT_ON_CLOSE);
System.exit(0); System.exit(0);
} }
}; };
// "Close" button override during match // "Close" button override during match
this.waConcede = new WindowAdapter() { this.waConcede = new WindowAdapter() {
@Override @Override
public void windowClosing(final WindowEvent e) { public void windowClosing(final WindowEvent e) {
Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
if (!FControl.this.game.isGameOver()) if (!FControl.this.game.isGameOver())
stopGame(); stopGame();
else { else {
Singletons.getControl().changeState(FControl.Screens.HOME_SCREEN); Singletons.getControl().changeState(FControl.Screens.HOME_SCREEN);
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
} }
}; };
// "Close" button override while inside bazaar (will probably be used later for other things) // "Close" button override while inside bazaar (will probably be used later for other things)
this.waLeaveBazaar = new WindowAdapter() { this.waLeaveBazaar = new WindowAdapter() {
@Override @Override
public void windowClosing(final WindowEvent e) { public void windowClosing(final WindowEvent e) {
Singletons.getView().getFrame().setDefaultCloseOperation( Singletons.getView().getFrame().setDefaultCloseOperation(
WindowConstants.DO_NOTHING_ON_CLOSE); WindowConstants.DO_NOTHING_ON_CLOSE);
changeState(Screens.HOME_SCREEN); changeState(Screens.HOME_SCREEN);
} }
}; };
this.waLeaveEditor = new WindowAdapter() { this.waLeaveEditor = new WindowAdapter() {
@Override @Override
public void windowClosing(final WindowEvent ev) { public void windowClosing(final WindowEvent ev) {
Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
if (CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().exit()) { if (CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().exit()) {
changeState(Screens.HOME_SCREEN); changeState(Screens.HOME_SCREEN);
} }
} }
}; };
} }
/** After view and model have been initialized, control can start. /** After view and model have been initialized, control can start.
* @param isHeadlessMode */ * @param isHeadlessMode */
public void initialize() { public void initialize() {
// Preloads skin components (using progress bar). // Preloads skin components (using progress bar).
FSkin.loadFull(); FSkin.loadFull();
//This must be done here or at least between the skin being loaded and any FTabbedPanes being created. //This must be done here or at least between the skin being loaded and any FTabbedPanes being created.
//Why,Swing? Why is this not a property of JTabbbedPane? //Why,Swing? Why is this not a property of JTabbbedPane?
UIManager.put("TabbedPane.selected", FSkin.getColor(FSkin.Colors.CLR_ACTIVE)); UIManager.put("TabbedPane.selected", FSkin.getColor(FSkin.Colors.CLR_ACTIVE));
UIManager.put("TabbedPane.contentOpaque", FSkin.getColor(FSkin.Colors.CLR_THEME)); UIManager.put("TabbedPane.contentOpaque", FSkin.getColor(FSkin.Colors.CLR_THEME));
UIManager.put("TabbedPane.unselectedBackground", FSkin.getColor(FSkin.Colors.CLR_THEME2)); UIManager.put("TabbedPane.unselectedBackground", FSkin.getColor(FSkin.Colors.CLR_THEME2));
setComboBoxLookAndFeel();
this.shortcuts = KeyboardShortcuts.attachKeyboardShortcuts();
this.display = FView.SINGLETON_INSTANCE.getLpnDocument(); this.shortcuts = KeyboardShortcuts.attachKeyboardShortcuts();
this.display = FView.SINGLETON_INSTANCE.getLpnDocument();
FSkin.setProgessBarMessage("About to load current quest.");
// Preload quest data if present FSkin.setProgessBarMessage("About to load current quest.");
final File dirQuests = new File(NewConstants.QUEST_SAVE_DIR); // Preload quest data if present
final String questname = Singletons.getModel().getQuestPreferences().getPref(QPref.CURRENT_QUEST); final File dirQuests = new File(NewConstants.QUEST_SAVE_DIR);
final File data = new File(dirQuests.getPath(), questname); final String questname = Singletons.getModel().getQuestPreferences().getPref(QPref.CURRENT_QUEST);
if (data.exists()) { final File data = new File(dirQuests.getPath(), questname);
Singletons.getModel().getQuest().load(QuestDataIO.loadData(data)); if (data.exists()) {
} Singletons.getModel().getQuest().load(QuestDataIO.loadData(data));
}
// Handles resizing in null layouts of layers in JLayeredPane as well as saving window layout
Singletons.getView().getFrame().addComponentListener(new ComponentAdapter() { // Handles resizing in null layouts of layers in JLayeredPane as well as saving window layout
@Override Singletons.getView().getFrame().addComponentListener(new ComponentAdapter() {
public void componentResized(final ComponentEvent e) { @Override
sizeChildren(); public void componentResized(final ComponentEvent e) {
SLayoutIO.saveWindowLayout(); sizeChildren();
} SLayoutIO.saveWindowLayout();
}
@Override
public void componentMoved(final ComponentEvent e) { @Override
SLayoutIO.saveWindowLayout(); public void componentMoved(final ComponentEvent e) {
} SLayoutIO.saveWindowLayout();
}); }
});
FView.SINGLETON_INSTANCE.getLpnDocument().addMouseListener(SOverflowUtil.getHideOverflowListener());
FView.SINGLETON_INSTANCE.getLpnDocument().addComponentListener(SResizingUtil.getWindowResizeListener()); FView.SINGLETON_INSTANCE.getLpnDocument().addMouseListener(SOverflowUtil.getHideOverflowListener());
FView.SINGLETON_INSTANCE.getLpnDocument().addComponentListener(SResizingUtil.getWindowResizeListener());
FSkin.setProgessBarMessage("Opening main window...");
SwingUtilities.invokeLater(new Runnable() { @Override FSkin.setProgessBarMessage("Opening main window...");
public void run() { Singletons.getView().initialize(); } }); SwingUtilities.invokeLater(new Runnable() { @Override
} public void run() { Singletons.getView().initialize(); } });
}
/**
* Switches between display states in top level JFrame. /**
*/ * @see <a href="http://tips4java.wordpress.com/2008/10/09/uimanager-defaults/">UIManager Defaults</a>
public void changeState(Screens screen) { */
//TODO: Uncomment the line below if this function stops being used to refresh private void setComboBoxLookAndFeel() {
//the current screen in some places (such as Continue and Restart in the match screen) if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_THEMED_COMBOBOX)) {
//if (this.state == screen) { return; } UIManager.put("ComboBox.background", FSkin.getColor(FSkin.Colors.CLR_THEME2));
UIManager.put("ComboBox.foreground", FSkin.getColor(FSkin.Colors.CLR_TEXT));
clearChildren(JLayeredPane.DEFAULT_LAYER); UIManager.put("ComboBox.selectionBackground", FSkin.getColor(FSkin.Colors.CLR_ACTIVE));
this.state = screen; UIManager.put("ComboBox.selectionForeground", FSkin.getColor(FSkin.Colors.CLR_TEXT));
UIManager.put("ComboBox.disabledBackground", FSkin.getColor(FSkin.Colors.CLR_THEME2));
Singletons.getView().getFrame().removeWindowListener(waDefault); UIManager.put("ComboBox.disabledForeground", FSkin.getColor(FSkin.Colors.CLR_THEME2).darker());
Singletons.getView().getFrame().removeWindowListener(waConcede); UIManager.put("Button.select", FSkin.getColor(FSkin.Colors.CLR_ACTIVE));
Singletons.getView().getFrame().removeWindowListener(waLeaveBazaar); UIManager.put("ComboBox.font", FSkin.getFont(UIManager.getFont("ComboBox.font").getSize()));
Singletons.getView().getFrame().removeWindowListener(waLeaveEditor); }
}
// Fire up new state
switch (screen) { /**
case HOME_SCREEN: * Switches between display states in top level JFrame.
SOverlayUtils.hideTargetingOverlay(); */
VHomeUI.SINGLETON_INSTANCE.populate(); public void changeState(Screens screen) {
CHomeUI.SINGLETON_INSTANCE.initialize(); //TODO: Uncomment the line below if this function stops being used to refresh
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true); //the current screen in some places (such as Continue and Restart in the match screen)
FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon()); //if (this.state == screen) { return; }
Singletons.getView().getFrame().addWindowListener(waDefault);
break; clearChildren(JLayeredPane.DEFAULT_LAYER);
this.state = screen;
case MATCH_SCREEN:
VMatchUI.SINGLETON_INSTANCE.populate(); Singletons.getView().getFrame().removeWindowListener(waDefault);
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true); Singletons.getView().getFrame().removeWindowListener(waConcede);
Singletons.getView().getFrame().removeWindowListener(waLeaveBazaar);
Singletons.getView().getFrame().removeWindowListener(waLeaveEditor);
// Fire up new state
switch (screen) {
case HOME_SCREEN:
SOverlayUtils.hideTargetingOverlay();
VHomeUI.SINGLETON_INSTANCE.populate();
CHomeUI.SINGLETON_INSTANCE.initialize();
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true);
FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon());
Singletons.getView().getFrame().addWindowListener(waDefault);
break;
case MATCH_SCREEN:
VMatchUI.SINGLETON_INSTANCE.populate();
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true);
showMatchBackgroundImage(); showMatchBackgroundImage();
Singletons.getView().getFrame().addWindowListener(waConcede); Singletons.getView().getFrame().addWindowListener(waConcede);
SOverlayUtils.showTargetingOverlay(); SOverlayUtils.showTargetingOverlay();
break; break;
case DECK_EDITOR_CONSTRUCTED: case DECK_EDITOR_CONSTRUCTED:
case DECK_EDITOR_LIMITED: case DECK_EDITOR_LIMITED:
case DECK_EDITOR_QUEST: case DECK_EDITOR_QUEST:
case QUEST_CARD_SHOP: case QUEST_CARD_SHOP:
case DRAFTING_PROCESS: case DRAFTING_PROCESS:
SOverlayUtils.hideTargetingOverlay(); SOverlayUtils.hideTargetingOverlay();
VDeckEditorUI.SINGLETON_INSTANCE.populate(); VDeckEditorUI.SINGLETON_INSTANCE.populate();
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true); FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true);
FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon()); FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon());
Singletons.getView().getFrame().addWindowListener(waLeaveEditor); Singletons.getView().getFrame().addWindowListener(waLeaveEditor);
break; break;
case QUEST_BAZAAR: case QUEST_BAZAAR:
SOverlayUtils.hideTargetingOverlay(); SOverlayUtils.hideTargetingOverlay();
display.add(Singletons.getView().getViewBazaar(), JLayeredPane.DEFAULT_LAYER); display.add(Singletons.getView().getViewBazaar(), JLayeredPane.DEFAULT_LAYER);
FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(false); FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(false);
sizeChildren(); sizeChildren();
Singletons.getView().getFrame().addWindowListener(waLeaveBazaar); Singletons.getView().getFrame().addWindowListener(waLeaveBazaar);
break; break;
default: default:
throw new RuntimeException("unhandled screen: " + screen); throw new RuntimeException("unhandled screen: " + screen);
} }
} }
private void showMatchBackgroundImage() { private void showMatchBackgroundImage() {
if (isMatchBackgroundImageVisible()) { if (isMatchBackgroundImageVisible()) {
FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(FSkin.getIcon(FSkin.Backgrounds.BG_MATCH)); FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(FSkin.getIcon(FSkin.Backgrounds.BG_MATCH));
@@ -277,185 +294,185 @@ public enum FControl {
return Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_MATCH_IMAGE_VISIBLE); return Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_MATCH_IMAGE_VISIBLE);
} }
public void changeStateAutoFixLayout(Screens newState, String stateName) { public void changeStateAutoFixLayout(Screens newState, String stateName) {
try { try {
changeState(newState); changeState(newState);
} catch (InvalidLayoutFileException ex) { } catch (InvalidLayoutFileException ex) {
GuiDialog.message("Your " + stateName + " layout file could not be read. It will be deleted after you press OK.\nThe game will proceed with default layout."); GuiDialog.message("Your " + stateName + " layout file could not be read. It will be deleted after you press OK.\nThe game will proceed with default layout.");
File fLayout = new File(SLayoutIO.getFilePreferred(newState)); File fLayout = new File(SLayoutIO.getFilePreferred(newState));
fLayout.delete(); fLayout.delete();
// try again // try again
changeState(newState); changeState(newState);
} }
} }
/** /**
* Returns the int reflecting the current state of the top level frame * Returns the int reflecting the current state of the top level frame
* (see field definitions and class methods for details). * (see field definitions and class methods for details).
* *
* @return {@link java.lang.Integer} * @return {@link java.lang.Integer}
* */ * */
public Screens getState() { public Screens getState() {
return this.state; return this.state;
} }
/** @return List<Shortcut> A list of attached keyboard shortcut descriptions and properties. */ /** @return List<Shortcut> A list of attached keyboard shortcut descriptions and properties. */
public List<Shortcut> getShortcuts() { public List<Shortcut> getShortcuts() {
return this.shortcuts; return this.shortcuts;
} }
/** Remove all children from a specified layer. */ /** Remove all children from a specified layer. */
private void clearChildren(final int layer0) { private void clearChildren(final int layer0) {
final Component[] children = FView.SINGLETON_INSTANCE.getLpnDocument() final Component[] children = FView.SINGLETON_INSTANCE.getLpnDocument()
.getComponentsInLayer(layer0); .getComponentsInLayer(layer0);
for (final Component c : children) { for (final Component c : children) {
display.remove(c); display.remove(c);
} }
} }
/** Sizes children of JLayeredPane to fully fit their layers. */ /** Sizes children of JLayeredPane to fully fit their layers. */
private void sizeChildren() { private void sizeChildren() {
Component[] children = display.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER); Component[] children = display.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER);
if (children.length != 0) { children[0].setSize(display.getSize()); } if (children.length != 0) { children[0].setSize(display.getSize()); }
children = display.getComponentsInLayer(FView.TARGETING_LAYER); children = display.getComponentsInLayer(FView.TARGETING_LAYER);
if (children.length != 0) { children[0].setSize(display.getSize()); } if (children.length != 0) { children[0].setSize(display.getSize()); }
children = display.getComponentsInLayer(JLayeredPane.MODAL_LAYER); children = display.getComponentsInLayer(JLayeredPane.MODAL_LAYER);
if (children.length != 0) { children[0].setSize(display.getSize()); } if (children.length != 0) { children[0].setSize(display.getSize()); }
} }
public Player getCurrentPlayer() { public Player getCurrentPlayer() {
// try current priority // try current priority
Player currentPriority = game.getPhaseHandler().getPriorityPlayer(); Player currentPriority = game.getPhaseHandler().getPriorityPlayer();
if( null != currentPriority && currentPriority.getLobbyPlayer() == FServer.instance.getLobby().getGuiPlayer() ) if( null != currentPriority && currentPriority.getLobbyPlayer() == FServer.instance.getLobby().getGuiPlayer() )
return currentPriority; return currentPriority;
// otherwise find just any player, belonging to this lobbyplayer // otherwise find just any player, belonging to this lobbyplayer
for(Player p : game.getPlayers()) for(Player p : game.getPlayers())
if(p.getLobbyPlayer() == FServer.instance.getLobby().getGuiPlayer() ) if(p.getLobbyPlayer() == FServer.instance.getLobby().getGuiPlayer() )
return p; return p;
return null; return null;
} }
public boolean mayShowCard(Card c) { public boolean mayShowCard(Card c) {
return game == null || !gameHasHumanPlayer || c.canBeShownTo(getCurrentPlayer()); return game == null || !gameHasHumanPlayer || c.canBeShownTo(getCurrentPlayer());
} }
/** /**
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
* @return * @return
*/ */
public SoundSystem getSoundSystem() { public SoundSystem getSoundSystem() {
return soundSystem; return soundSystem;
} }
private Game game; private Game game;
private boolean gameHasHumanPlayer; private boolean gameHasHumanPlayer;
public Game getObservedGame() { public Game getObservedGame() {
return game; return game;
} }
public final void stopGame() { public final void stopGame() {
List<Player> pp = new ArrayList<Player>(); List<Player> pp = new ArrayList<Player>();
for(Player p : game.getPlayers()) { for(Player p : game.getPlayers()) {
if ( p.getOriginalLobbyPlayer() == FServer.instance.getLobby().getGuiPlayer() ) if ( p.getOriginalLobbyPlayer() == FServer.instance.getLobby().getGuiPlayer() )
pp.add(p); pp.add(p);
} }
boolean hasHuman = !pp.isEmpty(); boolean hasHuman = !pp.isEmpty();
if ( pp.isEmpty() ) if ( pp.isEmpty() )
pp.addAll(game.getPlayers()); // no human? then all players surrender! pp.addAll(game.getPlayers()); // no human? then all players surrender!
for(Player p: pp) for(Player p: pp)
p.concede(); p.concede();
Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer(); Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer();
boolean humanHasPriority = priorityPlayer == null || priorityPlayer.getLobbyPlayer() == FServer.instance.getLobby().getGuiPlayer(); boolean humanHasPriority = priorityPlayer == null || priorityPlayer.getLobbyPlayer() == FServer.instance.getLobby().getGuiPlayer();
if ( hasHuman && humanHasPriority ) if ( hasHuman && humanHasPriority )
game.getAction().checkGameOverCondition(); game.getAction().checkGameOverCondition();
else else
game.isGameOver(); // this is synchronized method - it's used to make Game-0 thread see changes made here game.isGameOver(); // this is synchronized method - it's used to make Game-0 thread see changes made here
playbackControl.onGameStopRequested(); playbackControl.onGameStopRequested();
} }
private InputQueue inputQueue; private InputQueue inputQueue;
public InputQueue getInputQueue() { public InputQueue getInputQueue() {
return inputQueue; return inputQueue;
} }
public final void startGameWithUi(Match match) { public final void startGameWithUi(Match match) {
Game newGame = match.createGame(); Game newGame = match.createGame();
attachToGame(newGame); attachToGame(newGame);
match.startGame(newGame, null); match.startGame(newGame, null);
} }
private final FControlGameEventHandler fcVisitor = new FControlGameEventHandler(this); private final FControlGameEventHandler fcVisitor = new FControlGameEventHandler(this);
private final FControlGamePlayback playbackControl = new FControlGamePlayback(this); private final FControlGamePlayback playbackControl = new FControlGamePlayback(this);
private void attachToGame(Game game0) { private void attachToGame(Game game0) {
// TODO: Detach from other game we might be looking at // TODO: Detach from other game we might be looking at
if ( game0.getType() == GameType.Quest) { if ( game0.getType() == GameType.Quest) {
QuestController qc = Singletons.getModel().getQuest(); QuestController qc = Singletons.getModel().getQuest();
// Reset new list when the Match round starts, not when each game starts // Reset new list when the Match round starts, not when each game starts
if (game0.getMatch().getPlayedGames().isEmpty()) { if (game0.getMatch().getPlayedGames().isEmpty()) {
qc.getCards().resetNewList(); qc.getCards().resetNewList();
} }
game0.subscribeToEvents(qc); // this one listens to player's mulligans ATM game0.subscribeToEvents(qc); // this one listens to player's mulligans ATM
} }
inputQueue = new InputQueue(); inputQueue = new InputQueue();
this.game = game0; this.game = game0;
game.subscribeToEvents(Singletons.getControl().getSoundSystem()); game.subscribeToEvents(Singletons.getControl().getSoundSystem());
LobbyPlayer humanLobbyPlayer = FServer.instance.getLobby().getGuiPlayer(); LobbyPlayer humanLobbyPlayer = FServer.instance.getLobby().getGuiPlayer();
// The UI controls should use these game data as models // The UI controls should use these game data as models
CMatchUI.SINGLETON_INSTANCE.initMatch(game.getRegisteredPlayers(), humanLobbyPlayer); CMatchUI.SINGLETON_INSTANCE.initMatch(game.getRegisteredPlayers(), humanLobbyPlayer);
CDock.SINGLETON_INSTANCE.setModel(game, humanLobbyPlayer); CDock.SINGLETON_INSTANCE.setModel(game, humanLobbyPlayer);
CStack.SINGLETON_INSTANCE.setModel(game.getStack(), humanLobbyPlayer); CStack.SINGLETON_INSTANCE.setModel(game.getStack(), humanLobbyPlayer);
CLog.SINGLETON_INSTANCE.setModel(game.getGameLog()); CLog.SINGLETON_INSTANCE.setModel(game.getGameLog());
Singletons.getModel().getPreferences().actuateMatchPreferences(); Singletons.getModel().getPreferences().actuateMatchPreferences();
changeStateAutoFixLayout(Screens.MATCH_SCREEN, "match"); changeStateAutoFixLayout(Screens.MATCH_SCREEN, "match");
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
CMessage.SINGLETON_INSTANCE.getInputControl().setGame(game); CMessage.SINGLETON_INSTANCE.getInputControl().setGame(game);
// Listen to DuelOutcome event to show ViewWinLose // Listen to DuelOutcome event to show ViewWinLose
game.subscribeToEvents(fcVisitor); game.subscribeToEvents(fcVisitor);
// Add playback controls to match if needed // Add playback controls to match if needed
gameHasHumanPlayer = false; gameHasHumanPlayer = false;
for(Player p : game.getPlayers()) { for(Player p : game.getPlayers()) {
if ( p.getController().getLobbyPlayer() == FServer.instance.getLobby().getGuiPlayer() ) if ( p.getController().getLobbyPlayer() == FServer.instance.getLobby().getGuiPlayer() )
gameHasHumanPlayer = true; gameHasHumanPlayer = true;
} }
if (!gameHasHumanPlayer) { if (!gameHasHumanPlayer) {
game.subscribeToEvents(playbackControl); game.subscribeToEvents(playbackControl);
} }
VAntes.SINGLETON_INSTANCE.setModel(game.getRegisteredPlayers()); VAntes.SINGLETON_INSTANCE.setModel(game.getRegisteredPlayers());
for (final VField field : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) { for (final VField field : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) {
field.getDetailsPanel().getLblLibrary().setHoverable(Preferences.DEV_MODE); field.getDetailsPanel().getLblLibrary().setHoverable(Preferences.DEV_MODE);
} }
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch // per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch
//Set Field shown to current player. //Set Field shown to current player.
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(game.getPlayers().get(0)); VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(game.getPlayers().get(0));
SDisplayUtil.showTab(nextField); SDisplayUtil.showTab(nextField);
} }
} }

View File

@@ -96,8 +96,6 @@ public class FComboBoxPanel<E> extends JPanel {
lst0, val0, i0, isSelected, cellHasFocus); lst0, val0, i0, isSelected, cellHasFocus);
lblItem.setBorder(new EmptyBorder(4, 3, 4, 3)); lblItem.setBorder(new EmptyBorder(4, 3, 4, 3));
lblItem.setBackground(FSkin.getColor(hasFocus() ? FSkin.Colors.CLR_ACTIVE : FSkin.Colors.CLR_INACTIVE));
lblItem.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
lblItem.setFont(FSkin.getFont(12)); lblItem.setFont(FSkin.getFont(12));
lblItem.setOpaque(isSelected); lblItem.setOpaque(isSelected);
return lblItem; return lblItem;