Show context menu to select ability instead of dialog

This commit is contained in:
drdev
2013-11-10 20:25:25 +00:00
parent 4748aa2262
commit 1c13e8dc10
19 changed files with 120 additions and 40 deletions

View File

@@ -111,7 +111,6 @@ public class CostPutCounter extends CostPartWithList {
public int getTimesSelected(Card c) { public int getTimesSelected(Card c) {
return selected.contains(c) ? max == 1 || cardsChosen.get(c) == null ? 1 : cardsChosen.get(c).intValue() : 0; return selected.contains(c) ? max == 1 || cardsChosen.get(c) == null ? 1 : cardsChosen.get(c).intValue() : 0;
} }
} }
// Put Counter doesn't really have a "Valid" portion of the cost // Put Counter doesn't really have a "Valid" portion of the cost

View File

@@ -1,5 +1,6 @@
package forge.game.player; package forge.game.player;
import java.awt.event.MouseEvent;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -90,7 +91,14 @@ public abstract class PlayerController {
/** /**
* Uses GUI to learn which spell the player (human in our case) would like to play * Uses GUI to learn which spell the player (human in our case) would like to play
*/ */
public abstract SpellAbility getAbilityToPlay(List<SpellAbility> abilities); public SpellAbility getAbilityToPlay(List<SpellAbility> abilities) {
return getAbilityToPlay(abilities, null);
}
/**
* Uses GUI to learn which spell the player (human in our case) would like to play
*/
public abstract SpellAbility getAbilityToPlay(List<SpellAbility> abilities, MouseEvent triggerEvent);
/** /**
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.

View File

@@ -1,11 +1,13 @@
package forge.game.player; package forge.game.player;
import java.awt.event.MouseEvent;
import java.security.InvalidParameterException; import java.security.InvalidParameterException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@@ -62,7 +64,7 @@ public class PlayerControllerAi extends PlayerController {
/** /**
* Uses GUI to learn which spell the player (human in our case) would like to play * Uses GUI to learn which spell the player (human in our case) would like to play
*/ */
public SpellAbility getAbilityToPlay(List<SpellAbility> abilities) { public SpellAbility getAbilityToPlay(List<SpellAbility> abilities, MouseEvent triggerEvent) {
if (abilities.size() == 0) { if (abilities.size() == 0) {
return null; return null;
} else } else

View File

@@ -1,11 +1,16 @@
package forge.game.player; package forge.game.player;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import org.apache.commons.lang.math.IntRange; import org.apache.commons.lang.math.IntRange;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -51,6 +56,7 @@ import forge.gui.input.InputPlayOrDraw;
import forge.gui.input.InputSelectCards; import forge.gui.input.InputSelectCards;
import forge.gui.input.InputSelectCardsFromList; import forge.gui.input.InputSelectCardsFromList;
import forge.gui.match.CMatchUI; import forge.gui.match.CMatchUI;
import forge.gui.match.controllers.CMessage;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.util.Lang; import forge.util.Lang;
@@ -75,18 +81,41 @@ public class PlayerControllerHuman extends PlayerController {
return !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase); return !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase);
} }
/** /**
* Uses GUI to learn which spell the player (human in our case) would like to play * Uses GUI to learn which spell the player (human in our case) would like to play
*/ */
public SpellAbility getAbilityToPlay(List<SpellAbility> abilities) { public SpellAbility getAbilityToPlay(List<SpellAbility> abilities, MouseEvent triggerEvent) {
if (abilities.isEmpty()) { if (abilities.isEmpty()) {
return null; return null;
} else if (abilities.size() == 1) {
return abilities.get(0);
} else {
return GuiChoose.oneOrNone("Choose ability to play", abilities);
} }
if (abilities.size() == 1) {
return abilities.get(0);
}
if (triggerEvent == null) {
return GuiChoose.oneOrNone("Choose ability to play", abilities);
}
//show menu if mouse triggered ability
final JPopupMenu menu = new JPopupMenu("Abilities");
int shortcut = KeyEvent.VK_1; //use number keys as shortcuts for abilities 1-9
for (final SpellAbility ab : abilities) {
GuiUtils.addMenuItem(menu, ab.toString(),
shortcut > 0 ? KeyStroke.getKeyStroke(shortcut, 0) : null,
new Runnable() {
@Override
public void run() {
CMessage.SINGLETON_INSTANCE.getInputControl().selectAbility(ab);
}
});
shortcut++;
if (shortcut > KeyEvent.VK_9) {
shortcut = 0; //stop adding shortcuts after 9
}
}
menu.show(triggerEvent.getComponent(), triggerEvent.getX(), triggerEvent.getY());
return null; //delay ability until choice made
} }
/** /**

View File

@@ -17,6 +17,7 @@
*/ */
package forge.gui; package forge.gui;
import java.awt.event.MouseEvent;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@@ -24,6 +25,7 @@ import java.util.concurrent.atomic.AtomicReference;
import forge.Card; import forge.Card;
import forge.FThreads; import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.card.spellability.SpellAbility;
import forge.game.Game; import forge.game.Game;
import forge.game.player.Player; import forge.game.player.Player;
import forge.gui.input.Input; import forge.gui.input.Input;
@@ -113,13 +115,18 @@ public class InputProxy implements Observer {
* *
* @param card * @param card
* a {@link forge.Card} object. * a {@link forge.Card} object.
* @param zone * @param triggerEvent
* a {@link forge.game.zone.PlayerZone} object.
*/ */
public final void selectCard(final Card card, boolean isRightButton) { public final void selectCard(final Card card, final MouseEvent triggerEvent) {
Input inp = getInput(); Input inp = getInput();
if ( null != inp ) if ( null != inp )
inp.selectCard(card, isRightButton); inp.selectCard(card, triggerEvent);
}
public final void selectAbility(SpellAbility ab) {
Input inp = getInput();
if ( null != inp )
inp.selectAbility(ab);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

View File

@@ -1,6 +1,9 @@
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import forge.Card; import forge.Card;
import forge.card.spellability.SpellAbility;
import forge.game.player.Player; import forge.game.player.Player;
/** /**
@@ -12,7 +15,9 @@ public interface Input {
// showMessage() is always the first method called // showMessage() is always the first method called
void showMessageInitial(); void showMessageInitial();
void selectCard(Card c, boolean isMetaDown); void selectCard(Card c, MouseEvent triggerEvent);
void selectAbility(SpellAbility ab);
void selectPlayer(Player player); void selectPlayer(Player player);

View File

@@ -17,7 +17,9 @@
*/ */
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import java.util.List; import java.util.List;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import forge.Card; import forge.Card;
@@ -120,9 +122,9 @@ public class InputAttack extends InputSyncronizedBase {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
protected final void onCardSelected(final Card card, boolean isMetaDown) { protected final void onCardSelected(final Card card, final MouseEvent triggerEvent) {
final List<Card> att = combat.getAttackers(); final List<Card> att = combat.getAttackers();
if (isMetaDown && att.contains(card) && !card.hasKeyword("CARDNAME attacks each turn if able.") if (triggerEvent.getButton() == 3 && att.contains(card) && !card.hasKeyword("CARDNAME attacks each turn if able.")
&& !card.hasStartOfKeyword("CARDNAME attacks specific player each combat if able")) { && !card.hasStartOfKeyword("CARDNAME attacks specific player each combat if able")) {
// TODO Is there no way to attacks each turn cards to attack Planeswalkers? // TODO Is there no way to attacks each turn cards to attack Planeswalkers?
combat.removeFromCombat(card); combat.removeFromCombat(card);

View File

@@ -17,7 +17,10 @@
*/ */
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import forge.Card; import forge.Card;
import forge.card.spellability.SpellAbility;
import forge.game.Game; import forge.game.Game;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.player.Player; import forge.game.player.Player;
@@ -50,7 +53,10 @@ public abstract class InputBase implements java.io.Serializable, Input {
protected abstract void showMessage(); protected abstract void showMessage();
@Override @Override
public void selectPlayer(final Player player) { } public void selectPlayer(final Player player) { }
@Override
public void selectAbility(SpellAbility ab) { }
@Override @Override
@@ -66,12 +72,12 @@ public abstract class InputBase implements java.io.Serializable, Input {
} }
@Override @Override
public final void selectCard(Card c, boolean isMetaDown) { public final void selectCard(final Card c, final MouseEvent triggerEvent) {
if( isFinished() ) return; if( isFinished() ) return;
onCardSelected(c, isMetaDown); onCardSelected(c, triggerEvent);
} }
protected void onCardSelected(Card c, boolean isRmb) {} protected void onCardSelected(final Card c, final MouseEvent triggerEvent) {}
protected void onCancel() {} protected void onCancel() {}
protected void onOk() {} protected void onOk() {}

View File

@@ -17,6 +17,8 @@
*/ */
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import forge.Card; import forge.Card;
import forge.game.combat.Combat; import forge.game.combat.Combat;
import forge.game.combat.CombatUtil; import forge.game.combat.CombatUtil;
@@ -97,9 +99,9 @@ public class InputBlock extends InputSyncronizedBase {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public final void onCardSelected(final Card card, boolean isMetaDown) { public final void onCardSelected(final Card card, final MouseEvent triggerEvent) {
if (isMetaDown && card.getController() == defender) { if (triggerEvent.getButton() == 3 && card.getController() == defender) {
combat.removeFromCombat(card); combat.removeFromCombat(card);
CMatchUI.SINGLETON_INSTANCE.fireEvent(new UiEventBlockerAssigned(card, (Card)null)); CMatchUI.SINGLETON_INSTANCE.fireEvent(new UiEventBlockerAssigned(card, (Card)null));
} else { } else {

View File

@@ -17,6 +17,7 @@
*/ */
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -109,7 +110,7 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
volatile boolean cardSelectLocked = false; volatile boolean cardSelectLocked = false;
@Override @Override
protected void onCardSelected(final Card c0, boolean isRmb) { // the only place that would cause troubles - input is supposed only to confirm, not to fire abilities protected void onCardSelected(final Card c0, final MouseEvent triggerEvent) { // the only place that would cause troubles - input is supposed only to confirm, not to fire abilities
boolean fromHand = player.getZone(ZoneType.Hand).contains(c0); boolean fromHand = player.getZone(ZoneType.Hand).contains(c0);
boolean isSerumPowder = c0.getName().equals("Serum Powder"); boolean isSerumPowder = c0.getName().equals("Serum Powder");

View File

@@ -1,10 +1,12 @@
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import forge.Card; import forge.Card;
import forge.FThreads; import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.card.spellability.SpellAbility;
import forge.control.InputQueue; import forge.control.InputQueue;
import forge.game.player.Player; import forge.game.player.Player;
import forge.gui.match.CMatchUI; import forge.gui.match.CMatchUI;
@@ -62,7 +64,8 @@ public class InputLockUI implements Input {
CMatchUI.SINGLETON_INSTANCE.showMessage(message); CMatchUI.SINGLETON_INSTANCE.showMessage(message);
} }
@Override public void selectCard(Card c, boolean isMetaDown) {} @Override public void selectCard(Card c, MouseEvent triggerEvent) {}
@Override public void selectAbility(SpellAbility ab) {}
@Override public void selectPlayer(Player player) {} @Override public void selectPlayer(Player player) {}
@Override public void selectButtonOK() {} @Override public void selectButtonOK() {}
@Override public void selectButtonCancel() {} @Override public void selectButtonCancel() {}

View File

@@ -17,6 +17,9 @@
*/ */
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import java.util.List;
import forge.Card; import forge.Card;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.player.Player; import forge.game.player.Player;
@@ -59,14 +62,21 @@ public class InputPassPriority extends InputSyncronizedBase {
@Override @Override
protected void onCardSelected(Card card, boolean isRmb) { protected void onCardSelected(final Card card, final MouseEvent triggerEvent) {
final SpellAbility ab = player.getController().getAbilityToPlay(card.getAllPossibleAbilities(player)); List<SpellAbility> abilities = card.getAllPossibleAbilities(player);
if ( null != ab) { if (abilities.isEmpty()) {
flashIncorrectAction();
return;
}
selectAbility(player.getController().getAbilityToPlay(abilities, triggerEvent));
}
@Override
public void selectAbility(final SpellAbility ab) {
if (ab != null) {
chosenSa = ab; chosenSa = ab;
stop(); stop();
} }
else {
flashIncorrectAction();
}
} }
} }

View File

@@ -1,5 +1,6 @@
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -49,7 +50,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
@Override @Override
protected void onCardSelected(Card card, boolean isRmb) { protected void onCardSelected(final Card card, final MouseEvent triggerEvent) {
if (card.getManaAbility().isEmpty()) { if (card.getManaAbility().isEmpty()) {
flashIncorrectAction(); flashIncorrectAction();
return; return;

View File

@@ -1,5 +1,6 @@
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -81,7 +82,7 @@ public class InputPayManaX extends InputPayMana {
} }
@Override @Override
protected void onCardSelected(Card card, boolean isRmb) { protected void onCardSelected(final Card card, final MouseEvent triggerEvent) {
// don't allow here the cards that produce only wrong colors // don't allow here the cards that produce only wrong colors
activateManaAbility(card, this.manaCost); activateManaAbility(card, this.manaCost);
} }

View File

@@ -1,5 +1,6 @@
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -41,7 +42,7 @@ public final class InputProliferate extends InputSelectManyBase<GameEntity> {
} }
@Override @Override
protected void onCardSelected(Card card, boolean isRmb) { protected void onCardSelected(final Card card, final MouseEvent triggerEvent) {
if( !selectEntity(card) ) if( !selectEntity(card) )
return; return;

View File

@@ -1,5 +1,7 @@
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import forge.Card; import forge.Card;
public abstract class InputSelectCards extends InputSelectManyBase<Card> { public abstract class InputSelectCards extends InputSelectManyBase<Card> {
@@ -10,7 +12,7 @@ public abstract class InputSelectCards extends InputSelectManyBase<Card> {
} }
@Override @Override
protected void onCardSelected(Card c, boolean isRmb) { protected void onCardSelected(final Card c, final MouseEvent triggerEvent) {
if ( !selectEntity(c) ) if ( !selectEntity(c) )
return; return;

View File

@@ -1,5 +1,6 @@
package forge.gui.input; package forge.gui.input;
import java.awt.event.MouseEvent;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -101,7 +102,7 @@ public final class InputSelectTargets extends InputSyncronizedBase {
} }
@Override @Override
protected final void onCardSelected(Card card, boolean isRmb) { protected final void onCardSelected(final Card card, final MouseEvent triggerEvent) {
if (!tgt.isUniqueTargets() && targetDepth.containsKey(card)) { if (!tgt.isUniqueTargets() && targetDepth.containsKey(card)) {
return; return;
} }

View File

@@ -63,14 +63,14 @@ public class HandArea extends CardArea {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public final void mouseLeftClicked(final CardPanel panel, final MouseEvent evt) { public final void mouseLeftClicked(final CardPanel panel, final MouseEvent evt) {
CMessage.SINGLETON_INSTANCE.getInputControl().selectCard(panel.getCard(), false); CMessage.SINGLETON_INSTANCE.getInputControl().selectCard(panel.getCard(), evt);
super.mouseLeftClicked(panel, evt); super.mouseLeftClicked(panel, evt);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public final void mouseRightClicked(final CardPanel panel, final MouseEvent evt) { public final void mouseRightClicked(final CardPanel panel, final MouseEvent evt) {
CMessage.SINGLETON_INSTANCE.getInputControl().selectCard(panel.getCard(), true); CMessage.SINGLETON_INSTANCE.getInputControl().selectCard(panel.getCard(), evt);
super.mouseRightClicked(panel, evt); super.mouseRightClicked(panel, evt);
} }
} }

View File

@@ -501,7 +501,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public final void mouseLeftClicked(final CardPanel panel, final MouseEvent evt) { public final void mouseLeftClicked(final CardPanel panel, final MouseEvent evt) {
CMessage.SINGLETON_INSTANCE.getInputControl().selectCard(panel.getCard(), false); CMessage.SINGLETON_INSTANCE.getInputControl().selectCard(panel.getCard(), evt);
if ((panel.getTappedAngle() != 0) && (panel.getTappedAngle() != CardPanel.TAPPED_ANGLE)) { if ((panel.getTappedAngle() != 0) && (panel.getTappedAngle() != CardPanel.TAPPED_ANGLE)) {
return; return;
} }
@@ -511,7 +511,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public final void mouseRightClicked(final CardPanel panel, final MouseEvent evt) { public final void mouseRightClicked(final CardPanel panel, final MouseEvent evt) {
CMessage.SINGLETON_INSTANCE.getInputControl().selectCard(panel.getCard(), true); CMessage.SINGLETON_INSTANCE.getInputControl().selectCard(panel.getCard(), evt);
super.mouseRightClicked(panel, evt); super.mouseRightClicked(panel, evt);
} }