Fix many issues with the recent GUI and lobby refactorings.

- Fix closing screen of AI vs AI and multiplayer games
- Fix developer mode toggle boxes starting out in wrong state
- Fix storm count not displaying
- Fix deck selection when changing game variants
- Fix deck selection when returning to lobby after visiting a game
- Fix too many player panels appearing in games after a previous multiplayer game
This commit is contained in:
elcnesh
2015-03-18 17:08:18 +00:00
parent 19d02eed72
commit eeb67ab6e4
24 changed files with 288 additions and 185 deletions

View File

@@ -270,7 +270,7 @@ public class GuiDesktop implements IGuiBase {
public IGuiGame getNewGuiGame() {
return new CMatchUI();
};
}
@Override
public HostedMatch hostMatch() {

View File

@@ -245,7 +245,10 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
}
public Deck getDeck() {
DeckProxy proxy = lstDecks.getSelectedItem();
final DeckProxy proxy = lstDecks.getSelectedItem();
if (proxy == null) {
return null;
}
return proxy.getDeck();
}
@@ -271,12 +274,11 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
if (decksComboBox == null) { //initialize components with delayed initialization the first time this is populated
decksComboBox = new DecksComboBox();
lstDecksContainer = new ItemManagerContainer(lstDecks);
restoreSavedState();
decksComboBox.addListener(this);
restoreSavedState();
}
else {
removeAll();
restoreSavedState(); //ensure decks refreshed and state restored in case any deleted or added since last loaded
}
this.setLayout(new MigLayout("insets 0, gap 0"));
decksComboBox.addTo(this, "w 100%, h 30px!, gapbottom 5px, spanx 2, wrap");

View File

@@ -34,6 +34,7 @@ import forge.card.CardDetailUtil;
import forge.card.CardDetailUtil.DetailColors;
import forge.card.CardEdition;
import forge.card.CardRarity;
import forge.game.GameView;
import forge.game.card.Card;
import forge.game.card.CardView;
import forge.game.card.CardView.CardStateView;
@@ -69,6 +70,8 @@ public class CardDetailPanel extends SkinnedPanel {
private final FHtmlViewer cdArea;
private final FScrollPane scrArea;
private GameView gameView = null;
public CardDetailPanel() {
super();
setLayout(null);
@@ -100,6 +103,10 @@ public class CardDetailPanel extends SkinnedPanel {
add(scrArea);
}
public void setGameView(final GameView gameView) {
this.gameView = gameView;
}
@Override
public void doLayout() {
int insets = 3;
@@ -261,7 +268,7 @@ public class CardDetailPanel extends SkinnedPanel {
idLabel.setText(canShow ? CardDetailUtil.formatCardId(state) : "");
// fill the card text
cdArea.setText(FSkin.encodeSymbols(CardDetailUtil.composeCardText(state, canShow), true));
cdArea.setText(FSkin.encodeSymbols(CardDetailUtil.composeCardText(state, gameView, canShow), true));
SwingUtilities.invokeLater(new Runnable() {
@Override

View File

@@ -3,6 +3,8 @@
*/
package forge.gui.framework;
import com.google.common.collect.ObjectArrays;
import forge.screens.deckeditor.views.VAllDecks;
import forge.screens.deckeditor.views.VCardCatalog;
import forge.screens.deckeditor.views.VCurrentDeck;
@@ -126,6 +128,7 @@ public enum EDocID {
for (int i = 0; i < 8; i++) EDocID.Commands[i].setDoc(new VEmptyDoc(EDocID.Commands[i]));
for (int i = 0; i < 8; i++) EDocID.Hands[i].setDoc(new VEmptyDoc(EDocID.Hands[i]));
}
public final static EDocID[] VarDocs = ObjectArrays.concat(ObjectArrays.concat(Commands, Fields, EDocID.class), Hands, EDocID.class);
// End enum declarations, start enum methods.
private IVDoc<? extends ICDoc> vDoc;

View File

@@ -29,7 +29,7 @@ public class CLobby {
Vector<Object> listData;
Object val;
for (int i = 0; i < 8; i++) {
for (int i = 0; i < VLobby.MAX_PLAYERS; i++) {
// Commander: reinit deck list and restore last selections (if any)
deckList = view.getCommanderDeckLists().get(i);
listData = new Vector<Object>();

View File

@@ -228,7 +228,6 @@ public class PlayerPanel extends FPanel {
lobby.firePlayerChangeListener(index);
avatarLabel.requestFocusInWindow();
lobby.updateVanguardList(index);
lobby.update();
}
};
};
@@ -255,7 +254,6 @@ public class PlayerPanel extends FPanel {
prefs.save();
}
lobby.firePlayerChangeListener(index);
lobby.update();
}
}
};

View File

@@ -106,7 +106,7 @@ public class VLobby implements IUpdateable {
// Deck frame elements
private final JPanel decksFrame = new JPanel(new MigLayout("insets 0, gap 0, wrap, hidemode 3"));
private final List<FDeckChooser> deckChoosers = new ArrayList<FDeckChooser>(8);
private final List<FDeckChooser> deckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS);
private final FCheckBox cbSingletons = new FCheckBox("Singleton Mode");
private final FCheckBox cbArtifacts = new FCheckBox("Remove Artifacts");
private final Deck[] decks = new Deck[MAX_PLAYERS];
@@ -205,7 +205,7 @@ public class VLobby implements IUpdateable {
populateVanguardLists();
}
public void update() {
public void update(final boolean fullUpdate) {
activePlayersNum = lobby.getNumberOfSlots();
addPlayerBtn.setEnabled(activePlayersNum < MAX_PLAYERS);
@@ -221,19 +221,22 @@ public class VLobby implements IUpdateable {
// visible panels
final LobbySlot slot = lobby.getSlot(i);
final PlayerPanel panel;
final boolean isNewPanel;
if (hasPanel) {
panel = playerPanels.get(i);
panel.setVisible(true);
isNewPanel = !panel.isVisible();
} else {
panel = new PlayerPanel(this, allowNetworking, i, slot, lobby.mayEdit(i), lobby.hasControl());
playerPanels.add(panel);
String constraints = "pushx, growx, wrap, hidemode 3";
if (i == 0) {
constraints += ", gaptop 5px";
playerPanelWithFocus = panel;
playerPanelWithFocus.setFocused(true);
}
playersScroll.add(panel, constraints);
if (i == 0) {
changePlayerFocus(0);
}
isNewPanel = true;
}
panel.setType(slot.getType());
@@ -248,16 +251,24 @@ public class VLobby implements IUpdateable {
panel.setMayRemove(lobby.mayRemove(i));
panel.update();
deckChoosers.get(i).setIsAi(slot.getType() == LobbySlotType.AI);
final FDeckChooser deckChooser = getDeckChooser(i);
deckChooser.setIsAi(slot.getType() == LobbySlotType.AI);
if (fullUpdate) {
selectDeck(i);
}
if (isNewPanel) {
panel.setVisible(true);
}
} else if (hasPanel) {
playerPanels.get(i).setVisible(false);
}
}
if (playerWithFocus >= activePlayersNum) {
playerWithFocus = activePlayersNum - 1;
changePlayerFocus(activePlayersNum - 1);
} else {
populateDeckPanel(getCurrentGameMode());
}
changePlayerFocus(playerWithFocus);
refreshPanels(true, true);
}
@@ -268,7 +279,7 @@ public class VLobby implements IUpdateable {
void setReady(final int index, final boolean ready) {
if (ready && decks[index] == null) {
GuiBase.getInterface().showOptionDialog("Select a deck before readying!", "Error", FSkinProp.ICO_WARNING, new String[] { "Ok" }, 0);
update();
update(false);
return;
}
@@ -280,13 +291,13 @@ public class VLobby implements IUpdateable {
playerChangeListener.update(index, getSlot(index));
}
}
void fireDeckChangeListener(final int index, final Deck deck) {
private void fireDeckChangeListener(final int index, final Deck deck) {
decks[index] = deck;
if (playerChangeListener != null) {
playerChangeListener.update(index, UpdateLobbyPlayerEvent.deckUpdate(deck));
}
}
void fireDeckSectionChangeListener(final int index, final DeckSection section, final CardPool cards) {
private void fireDeckSectionChangeListener(final int index, final DeckSection section, final CardPool cards) {
decks[index].putSection(section, cards);
if (playerChangeListener != null) {
playerChangeListener.update(index, UpdateLobbyPlayerEvent.deckUpdate(section, cards));
@@ -314,12 +325,12 @@ public class VLobby implements IUpdateable {
// Main deck
final FDeckChooser mainChooser = new FDeckChooser(null, false);
mainChooser.initialize();
mainChooser.getLstDecks().setSelectCommand(new UiCommand() {
@Override public final void run() {
VLobby.this.onDeckClicked(playerIndex, mainChooser.getSelectedDeckType(), mainChooser.getLstDecks().getSelectedItems());
selectMainDeck(playerIndex);
}
});
mainChooser.initialize();
deckChoosers.add(mainChooser);
// Scheme deck list
@@ -331,34 +342,7 @@ public class VLobby implements IUpdateable {
schemeDeckList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
schemeDeckList.addListSelectionListener(new ListSelectionListener() {
@Override public final void valueChanged(final ListSelectionEvent e) {
if (playerIndex >= activePlayersNum) {
return;
}
final Object selected = schemeDeckList.getSelectedValue();
final Deck deck = decks[playerIndex];
CardPool schemePool = null;
if (selected instanceof String) {
String sel = (String) selected;
if (sel.contains("Use deck's scheme section")) {
if (deck.has(DeckSection.Schemes)) {
schemePool = deck.get(DeckSection.Schemes);
} else {
sel = "Random";
}
}
final IStorage<Deck> sDecks = FModel.getDecks().getScheme();
if (sel.equals("Random") && sDecks.size() != 0) {
schemePool = Aggregates.random(sDecks).get(DeckSection.Schemes);
}
} else if (selected instanceof Deck) {
schemePool = ((Deck) selected).get(DeckSection.Schemes);
}
if (schemePool == null) { //Can be null if player deselects the list selection or chose Generate
schemePool = DeckgenUtil.generateSchemePool();
}
fireDeckSectionChangeListener(playerIndex, DeckSection.Schemes, schemePool);
getDeckChooser(playerIndex).saveState();
selectSchemeDeck(playerIndex);
}
});
@@ -377,30 +361,9 @@ public class VLobby implements IUpdateable {
commanderDeckList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
commanderDeckList.addListSelectionListener(new ListSelectionListener() {
@Override public final void valueChanged(final ListSelectionEvent e) {
if (playerIndex >= activePlayersNum) {
return;
}
final Object selected = commanderDeckList.getSelectedValue();
Deck deck = null;
if (selected instanceof String) {
final String sel = (String) selected;
final IStorage<Deck> comDecks = FModel.getDecks().getCommander();
if (sel.equals("Random") && comDecks.size() > 0) {
deck = Aggregates.random(comDecks);
}
} else if (selected instanceof Deck) {
deck = (Deck) selected;
}
final GameType commanderGameType = hasVariant(GameType.TinyLeaders) ? GameType.TinyLeaders : GameType.Commander;
if (deck == null) { //Can be null if player deselects the list selection or chose Generate
deck = DeckgenUtil.generateCommanderDeck(isPlayerAI(playerIndex), commanderGameType);
}
fireDeckChangeListener(playerIndex, deck);
getDeckChooser(playerIndex).saveState();
selectCommanderDeck(playerIndex);
}
});
final FScrollPane scrCommander = new FScrollPane(commanderDeckList, true,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
@@ -417,34 +380,7 @@ public class VLobby implements IUpdateable {
planarDeckList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
planarDeckList.addListSelectionListener(new ListSelectionListener() {
@Override public final void valueChanged(final ListSelectionEvent e) {
if (playerIndex >= activePlayersNum) {
return;
}
final Object selected = planarDeckList.getSelectedValue();
final Deck deck = decks[playerIndex];
CardPool planePool = null;
if (selected instanceof String) {
String sel = (String) selected;
if (sel.contains("Use deck's planes section")) {
if (deck.has(DeckSection.Planes)) {
planePool = deck.get(DeckSection.Planes);
} else {
sel = "Random";
}
}
final IStorage<Deck> pDecks = FModel.getDecks().getPlane();
if (sel.equals("Random") && pDecks.size() != 0) {
planePool = Aggregates.random(pDecks).get(DeckSection.Planes);
}
} else if (selected instanceof Deck) {
planePool = ((Deck) selected).get(DeckSection.Planes);
}
if (planePool == null) { //Can be null if player deselects the list selection or chose Generate
planePool = DeckgenUtil.generatePlanarPool();
}
fireDeckSectionChangeListener(playerIndex, DeckSection.Planes, planePool);
getDeckChooser(playerIndex).saveState();
selectPlanarDeck(playerIndex);
}
});
@@ -477,11 +413,114 @@ public class VLobby implements IUpdateable {
vgdPanels.add(vgdDeckPanel);
}
protected void onDeckClicked(final int iPlayer, final DeckType type, final Collection<DeckProxy> selectedDecks) {
private void selectDeck(final int playerIndex) {
selectMainDeck(playerIndex);
selectCommanderDeck(playerIndex);
selectSchemeDeck(playerIndex);
selectPlanarDeck(playerIndex);
}
private void selectMainDeck(final int playerIndex) {
if (hasVariant(GameType.Commander) || hasVariant(GameType.TinyLeaders)) {
// These game types use specific deck panel
return;
}
final FDeckChooser mainChooser = getDeckChooser(playerIndex);
VLobby.this.onDeckClicked(playerIndex, mainChooser.getSelectedDeckType(), mainChooser.getDeck(), mainChooser.getLstDecks().getSelectedItems());
getDeckChooser(playerIndex).saveState();
}
private void selectSchemeDeck(final int playerIndex) {
if (playerIndex >= activePlayersNum || !(hasVariant(GameType.Archenemy) || hasVariant(GameType.ArchenemyRumble))) {
return;
}
final Object selected = getSchemeDeckLists().get(playerIndex).getSelectedValue();
final Deck deck = decks[playerIndex];
CardPool schemePool = null;
if (selected instanceof String) {
String sel = (String) selected;
if (sel.contains("Use deck's scheme section")) {
if (deck.has(DeckSection.Schemes)) {
schemePool = deck.get(DeckSection.Schemes);
} else {
sel = "Random";
}
}
final IStorage<Deck> sDecks = FModel.getDecks().getScheme();
if (sel.equals("Random") && sDecks.size() != 0) {
schemePool = Aggregates.random(sDecks).get(DeckSection.Schemes);
}
} else if (selected instanceof Deck) {
schemePool = ((Deck) selected).get(DeckSection.Schemes);
}
if (schemePool == null) { //Can be null if player deselects the list selection or chose Generate
schemePool = DeckgenUtil.generateSchemePool();
}
fireDeckSectionChangeListener(playerIndex, DeckSection.Schemes, schemePool);
getDeckChooser(playerIndex).saveState();
}
private void selectCommanderDeck(final int playerIndex) {
if (playerIndex >= activePlayersNum || !(hasVariant(GameType.Commander) || hasVariant(GameType.TinyLeaders))) {
return;
}
final Object selected = getCommanderDeckLists().get(playerIndex).getSelectedValue();
Deck deck = null;
if (selected instanceof String) {
final String sel = (String) selected;
final IStorage<Deck> comDecks = FModel.getDecks().getCommander();
if (sel.equals("Random") && comDecks.size() > 0) {
deck = Aggregates.random(comDecks);
}
} else if (selected instanceof Deck) {
deck = (Deck) selected;
}
final GameType commanderGameType = hasVariant(GameType.TinyLeaders) ? GameType.TinyLeaders : GameType.Commander;
if (deck == null) { //Can be null if player deselects the list selection or chose Generate
deck = DeckgenUtil.generateCommanderDeck(isPlayerAI(playerIndex), commanderGameType);
}
fireDeckChangeListener(playerIndex, deck);
getDeckChooser(playerIndex).saveState();
}
private void selectPlanarDeck(final int playerIndex) {
if (playerIndex >= activePlayersNum) {
return;
}
final Object selected = getPlanarDeckLists().get(playerIndex).getSelectedValue();
final Deck deck = decks[playerIndex];
CardPool planePool = null;
if (selected instanceof String) {
String sel = (String) selected;
if (sel.contains("Use deck's planes section")) {
if (deck.has(DeckSection.Planes)) {
planePool = deck.get(DeckSection.Planes);
} else {
sel = "Random";
}
}
final IStorage<Deck> pDecks = FModel.getDecks().getPlane();
if (sel.equals("Random") && pDecks.size() != 0) {
planePool = Aggregates.random(pDecks).get(DeckSection.Planes);
}
} else if (selected instanceof Deck) {
planePool = ((Deck) selected).get(DeckSection.Planes);
}
if (planePool == null) { //Can be null if player deselects the list selection or chose Generate
planePool = DeckgenUtil.generatePlanarPool();
}
fireDeckSectionChangeListener(playerIndex, DeckSection.Planes, planePool);
getDeckChooser(playerIndex).saveState();
}
protected void onDeckClicked(final int iPlayer, final DeckType type, final Deck deck, final Collection<DeckProxy> selectedDecks) {
if (iPlayer < activePlayersNum && lobby.mayEdit(iPlayer)) {
final String text = type.toString() + ": " + Lang.joinHomogenous(selectedDecks, DeckProxy.FN_GET_NAME);
playerPanels.get(iPlayer).setDeckSelectorButtonText(text);
fireDeckChangeListener(iPlayer, selectedDecks.iterator().next().getDeck());
fireDeckChangeListener(iPlayer, deck);
}
}
@@ -560,10 +599,10 @@ public class VLobby implements IUpdateable {
}
void setCurrentGameMode(final GameType mode) {
lobby.setGameType(mode);
update();
update(true);
}
public boolean isPlayerAI(final int playernum) {
private boolean isPlayerAI(final int playernum) {
return playernum < activePlayersNum ? playerPanels.get(playernum).isAi() : false;
}
@@ -588,7 +627,9 @@ public class VLobby implements IUpdateable {
}
void changePlayerFocus(int newFocusOwner, GameType gType) {
playerPanelWithFocus.setFocused(false);
if (playerPanelWithFocus != null) {
playerPanelWithFocus.setFocused(false);
}
playerWithFocus = newFocusOwner;
playerPanelWithFocus = playerPanels.get(playerWithFocus);
playerPanelWithFocus.setFocused(true);
@@ -675,7 +716,6 @@ public class VLobby implements IUpdateable {
} else {
lobby.removeVariant(variantType);
}
VLobby.this.update();
}
});
}

View File

@@ -45,8 +45,8 @@ public enum CSubmenuOnlineLobby implements ICDoc, IMenuProvider {
FNetOverlay.SINGLETON_INSTANCE.showUp("Hosting game");
lobby.setListener(new IUpdateable() {
@Override public final void update() {
view.update();
@Override public final void update(final boolean fullUpdate) {
view.update(fullUpdate);
server.updateLobbyState();
}
});
@@ -79,7 +79,7 @@ public enum CSubmenuOnlineLobby implements ICDoc, IMenuProvider {
}
});
view.update();
view.update(true);
Singletons.getControl().setCurrentScreen(FScreen.ONLINE_LOBBY);
FNetOverlay.SINGLETON_INSTANCE.showUp(String.format("Hosting on port %d", portNumber));

View File

@@ -42,7 +42,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
}
});
vLobby.update();
vLobby.update(false);
}
public VLobby getLobby() {

View File

@@ -66,12 +66,14 @@ import forge.gui.GuiChoose;
import forge.gui.GuiDialog;
import forge.gui.GuiUtils;
import forge.gui.SOverlayUtils;
import forge.gui.framework.DragCell;
import forge.gui.framework.EDocID;
import forge.gui.framework.FScreen;
import forge.gui.framework.ICDoc;
import forge.gui.framework.IVDoc;
import forge.gui.framework.SDisplayUtil;
import forge.gui.framework.SLayoutIO;
import forge.gui.framework.VEmptyDoc;
import forge.interfaces.IButton;
import forge.item.InventoryItem;
import forge.item.PaperCard;
@@ -181,6 +183,7 @@ public final class CMatchUI
@Override
public void setGameView(final GameView gameView) {
super.setGameView(gameView);
cDetailPicture.setGameView(gameView);
screen.setTabCaption(gameView.getTitle());
if (sortedPlayers != null) {
for (final PlayerView pv : sortedPlayers) {
@@ -516,6 +519,16 @@ public final class CMatchUI
public void register() {
initHandViews();
registerDocs();
for (final EDocID fieldDoc : EDocID.VarDocs) {
// Remove unnecessary docs for this match
if (!myDocs.containsKey(fieldDoc)) {
final DragCell parent = fieldDoc.getDoc().getParentCell();
if (parent != null) {
parent.removeDoc(fieldDoc.getDoc());
fieldDoc.setDoc(new VEmptyDoc(fieldDoc));
}
}
}
}
@Override

View File

@@ -7,7 +7,6 @@ import java.util.List;
import javax.swing.SwingUtilities;
import forge.Singletons;
import forge.game.GameView;
import forge.gui.framework.DragCell;
import forge.gui.framework.EDocID;
import forge.gui.framework.FScreen;
@@ -196,18 +195,16 @@ public class VMatchUI implements IVTopLevelUI {
@Override
public boolean onClosing(final FScreen screen) {
if (!Singletons.getControl().getCurrentScreen().equals(screen)) {
// Switch to this screen if not already showing
Singletons.getControl().setCurrentScreen(screen);
}
final GameView gameView = control.getGameView();
if (gameView != null && !gameView.isGameOver()) {
control.concede();
return false; //delay hiding tab even if concede successful
if (control.concede()) {
//switch back to menus music when closing screen
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS);
return true;
}
//switch back to menus music when closing screen
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS);
return true;
return false;
}
}

View File

@@ -1,5 +1,6 @@
package forge.screens.match.controllers;
import forge.game.GameView;
import forge.game.card.Card;
import forge.game.card.CardView;
import forge.interfaces.IMayViewCards;
@@ -75,6 +76,10 @@ public class CDetailPicture {
}
}
public void setGameView(final GameView gameView) {
cDetail.getView().setGameView(gameView);
}
void flip() {
if (mayFlip()) {
isDisplayAlt = !isDisplayAlt;

View File

@@ -61,7 +61,7 @@ public class CDev implements ICDoc {
private final MouseListener madViewAll = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
public void mousePressed(final MouseEvent e) {
toggleViewAllCards();
}
};
@@ -228,8 +228,8 @@ public class CDev implements ICDoc {
@Override
public void update() {
if (getController() != null) {
view.getLblUnlimitedLands().setToggled(!getController().canPlayUnlimitedLands());
view.getLblViewAll().setToggled(!getController().mayLookAtAllCards());
view.getLblUnlimitedLands().setToggled(getController().canPlayUnlimitedLands());
view.getLblViewAll().setToggled(getController().mayLookAtAllCards());
}
}
}

View File

@@ -18,6 +18,7 @@
package forge.screens.match.views;
import forge.assets.FSkinProp;
import forge.game.GameView;
import forge.gui.CardDetailPanel;
import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab;
@@ -54,6 +55,10 @@ public class VDetail implements IVDoc<CDetail> {
lblFlipcard.setVisible(false);
}
public void setGameView(final GameView gameView) {
this.pnlDetail.setGameView(gameView);
}
//========= Overridden methods
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#populate()