From 1c13e8dc108d0f73e2653ea6397c1b2a16b797b0 Mon Sep 17 00:00:00 2001 From: drdev Date: Sun, 10 Nov 2013 20:25:25 +0000 Subject: [PATCH] Show context menu to select ability instead of dialog --- .../java/forge/card/cost/CostPutCounter.java | 1 - .../forge/game/player/PlayerController.java | 10 ++++- .../forge/game/player/PlayerControllerAi.java | 4 +- .../game/player/PlayerControllerHuman.java | 43 ++++++++++++++++--- .../src/main/java/forge/gui/InputProxy.java | 15 +++++-- .../src/main/java/forge/gui/input/Input.java | 7 ++- .../java/forge/gui/input/InputAttack.java | 6 ++- .../main/java/forge/gui/input/InputBase.java | 14 ++++-- .../main/java/forge/gui/input/InputBlock.java | 6 ++- .../forge/gui/input/InputConfirmMulligan.java | 3 +- .../java/forge/gui/input/InputLockUI.java | 5 ++- .../forge/gui/input/InputPassPriority.java | 22 +++++++--- .../java/forge/gui/input/InputPayMana.java | 3 +- .../java/forge/gui/input/InputPayManaX.java | 3 +- .../forge/gui/input/InputProliferate.java | 3 +- .../forge/gui/input/InputSelectCards.java | 4 +- .../forge/gui/input/InputSelectTargets.java | 3 +- .../main/java/forge/view/arcane/HandArea.java | 4 +- .../main/java/forge/view/arcane/PlayArea.java | 4 +- 19 files changed, 120 insertions(+), 40 deletions(-) diff --git a/forge-gui/src/main/java/forge/card/cost/CostPutCounter.java b/forge-gui/src/main/java/forge/card/cost/CostPutCounter.java index 901c041a819..ab0f56ff1b1 100644 --- a/forge-gui/src/main/java/forge/card/cost/CostPutCounter.java +++ b/forge-gui/src/main/java/forge/card/cost/CostPutCounter.java @@ -111,7 +111,6 @@ public class CostPutCounter extends CostPartWithList { public int getTimesSelected(Card c) { 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 diff --git a/forge-gui/src/main/java/forge/game/player/PlayerController.java b/forge-gui/src/main/java/forge/game/player/PlayerController.java index cbf4eaef3be..089b37e7edd 100644 --- a/forge-gui/src/main/java/forge/game/player/PlayerController.java +++ b/forge-gui/src/main/java/forge/game/player/PlayerController.java @@ -1,5 +1,6 @@ package forge.game.player; +import java.awt.event.MouseEvent; import java.util.Collection; import java.util.HashMap; 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 */ - public abstract SpellAbility getAbilityToPlay(List abilities); + public SpellAbility getAbilityToPlay(List 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 abilities, MouseEvent triggerEvent); /** * TODO: Write javadoc for this method. diff --git a/forge-gui/src/main/java/forge/game/player/PlayerControllerAi.java b/forge-gui/src/main/java/forge/game/player/PlayerControllerAi.java index 91fb51e11f9..096866105c0 100644 --- a/forge-gui/src/main/java/forge/game/player/PlayerControllerAi.java +++ b/forge-gui/src/main/java/forge/game/player/PlayerControllerAi.java @@ -1,11 +1,13 @@ package forge.game.player; +import java.awt.event.MouseEvent; import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; + import org.apache.commons.lang3.tuple.ImmutablePair; 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 */ - public SpellAbility getAbilityToPlay(List abilities) { + public SpellAbility getAbilityToPlay(List abilities, MouseEvent triggerEvent) { if (abilities.size() == 0) { return null; } else diff --git a/forge-gui/src/main/java/forge/game/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/game/player/PlayerControllerHuman.java index f02eee279f0..52978f59ae8 100644 --- a/forge-gui/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -1,11 +1,16 @@ package forge.game.player; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; + import javax.swing.JOptionPane; +import javax.swing.JPopupMenu; +import javax.swing.KeyStroke; import org.apache.commons.lang.math.IntRange; import org.apache.commons.lang3.StringUtils; @@ -51,6 +56,7 @@ import forge.gui.input.InputPlayOrDraw; import forge.gui.input.InputSelectCards; import forge.gui.input.InputSelectCardsFromList; import forge.gui.match.CMatchUI; +import forge.gui.match.controllers.CMessage; import forge.item.PaperCard; import forge.properties.ForgePreferences.FPref; import forge.util.Lang; @@ -75,18 +81,41 @@ public class PlayerControllerHuman extends PlayerController { return !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase); } - /** * Uses GUI to learn which spell the player (human in our case) would like to play */ - public SpellAbility getAbilityToPlay(List abilities) { - if (abilities.isEmpty()) { + public SpellAbility getAbilityToPlay(List abilities, MouseEvent triggerEvent) { + if (abilities.isEmpty()) { 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 } /** diff --git a/forge-gui/src/main/java/forge/gui/InputProxy.java b/forge-gui/src/main/java/forge/gui/InputProxy.java index 29b466c287e..7ee43779ec3 100644 --- a/forge-gui/src/main/java/forge/gui/InputProxy.java +++ b/forge-gui/src/main/java/forge/gui/InputProxy.java @@ -17,6 +17,7 @@ */ package forge.gui; +import java.awt.event.MouseEvent; import java.util.Observable; import java.util.Observer; import java.util.concurrent.atomic.AtomicReference; @@ -24,6 +25,7 @@ import java.util.concurrent.atomic.AtomicReference; import forge.Card; import forge.FThreads; import forge.Singletons; +import forge.card.spellability.SpellAbility; import forge.game.Game; import forge.game.player.Player; import forge.gui.input.Input; @@ -113,13 +115,18 @@ public class InputProxy implements Observer { * * @param card * a {@link forge.Card} object. - * @param zone - * a {@link forge.game.zone.PlayerZone} object. + * @param triggerEvent */ - public final void selectCard(final Card card, boolean isRightButton) { + public final void selectCard(final Card card, final MouseEvent triggerEvent) { Input inp = getInput(); 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} */ diff --git a/forge-gui/src/main/java/forge/gui/input/Input.java b/forge-gui/src/main/java/forge/gui/input/Input.java index eda650c79b9..1d45e8c1fb1 100644 --- a/forge-gui/src/main/java/forge/gui/input/Input.java +++ b/forge-gui/src/main/java/forge/gui/input/Input.java @@ -1,6 +1,9 @@ package forge.gui.input; +import java.awt.event.MouseEvent; + import forge.Card; +import forge.card.spellability.SpellAbility; import forge.game.player.Player; /** @@ -12,7 +15,9 @@ public interface Input { // showMessage() is always the first method called void showMessageInitial(); - void selectCard(Card c, boolean isMetaDown); + void selectCard(Card c, MouseEvent triggerEvent); + + void selectAbility(SpellAbility ab); void selectPlayer(Player player); diff --git a/forge-gui/src/main/java/forge/gui/input/InputAttack.java b/forge-gui/src/main/java/forge/gui/input/InputAttack.java index e0369e3f2c2..8b28b4dd2df 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputAttack.java +++ b/forge-gui/src/main/java/forge/gui/input/InputAttack.java @@ -17,7 +17,9 @@ */ package forge.gui.input; +import java.awt.event.MouseEvent; import java.util.List; + import com.google.common.collect.Iterables; import forge.Card; @@ -120,9 +122,9 @@ public class InputAttack extends InputSyncronizedBase { /** {@inheritDoc} */ @Override - protected final void onCardSelected(final Card card, boolean isMetaDown) { + protected final void onCardSelected(final Card card, final MouseEvent triggerEvent) { final List 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")) { // TODO Is there no way to attacks each turn cards to attack Planeswalkers? combat.removeFromCombat(card); diff --git a/forge-gui/src/main/java/forge/gui/input/InputBase.java b/forge-gui/src/main/java/forge/gui/input/InputBase.java index f94c5710e03..a2ff0e83f0f 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputBase.java +++ b/forge-gui/src/main/java/forge/gui/input/InputBase.java @@ -17,7 +17,10 @@ */ package forge.gui.input; +import java.awt.event.MouseEvent; + import forge.Card; +import forge.card.spellability.SpellAbility; import forge.game.Game; import forge.game.phase.PhaseHandler; import forge.game.player.Player; @@ -50,7 +53,10 @@ public abstract class InputBase implements java.io.Serializable, Input { protected abstract void showMessage(); @Override - public void selectPlayer(final Player player) { } + public void selectPlayer(final Player player) { } + + @Override + public void selectAbility(SpellAbility ab) { } @Override @@ -66,12 +72,12 @@ public abstract class InputBase implements java.io.Serializable, Input { } @Override - public final void selectCard(Card c, boolean isMetaDown) { + public final void selectCard(final Card c, final MouseEvent triggerEvent) { 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 onOk() {} diff --git a/forge-gui/src/main/java/forge/gui/input/InputBlock.java b/forge-gui/src/main/java/forge/gui/input/InputBlock.java index 1137ddd47ef..8b710b5e007 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputBlock.java +++ b/forge-gui/src/main/java/forge/gui/input/InputBlock.java @@ -17,6 +17,8 @@ */ package forge.gui.input; +import java.awt.event.MouseEvent; + import forge.Card; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; @@ -97,9 +99,9 @@ public class InputBlock extends InputSyncronizedBase { /** {@inheritDoc} */ @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); CMatchUI.SINGLETON_INSTANCE.fireEvent(new UiEventBlockerAssigned(card, (Card)null)); } else { diff --git a/forge-gui/src/main/java/forge/gui/input/InputConfirmMulligan.java b/forge-gui/src/main/java/forge/gui/input/InputConfirmMulligan.java index 99e6a27fe7e..eb67ad89ae2 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputConfirmMulligan.java +++ b/forge-gui/src/main/java/forge/gui/input/InputConfirmMulligan.java @@ -17,6 +17,7 @@ */ package forge.gui.input; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; @@ -109,7 +110,7 @@ public class InputConfirmMulligan extends InputSyncronizedBase { volatile boolean cardSelectLocked = false; @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 isSerumPowder = c0.getName().equals("Serum Powder"); diff --git a/forge-gui/src/main/java/forge/gui/input/InputLockUI.java b/forge-gui/src/main/java/forge/gui/input/InputLockUI.java index 6432c6dd8dd..cb5a4beeef0 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputLockUI.java +++ b/forge-gui/src/main/java/forge/gui/input/InputLockUI.java @@ -1,10 +1,12 @@ package forge.gui.input; +import java.awt.event.MouseEvent; import java.util.concurrent.atomic.AtomicInteger; import forge.Card; import forge.FThreads; import forge.Singletons; +import forge.card.spellability.SpellAbility; import forge.control.InputQueue; import forge.game.player.Player; import forge.gui.match.CMatchUI; @@ -62,7 +64,8 @@ public class InputLockUI implements Input { 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 selectButtonOK() {} @Override public void selectButtonCancel() {} diff --git a/forge-gui/src/main/java/forge/gui/input/InputPassPriority.java b/forge-gui/src/main/java/forge/gui/input/InputPassPriority.java index 8d62e81cbff..5e06b43c83b 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputPassPriority.java +++ b/forge-gui/src/main/java/forge/gui/input/InputPassPriority.java @@ -17,6 +17,9 @@ */ package forge.gui.input; +import java.awt.event.MouseEvent; +import java.util.List; + import forge.Card; import forge.card.spellability.SpellAbility; import forge.game.player.Player; @@ -59,14 +62,21 @@ public class InputPassPriority extends InputSyncronizedBase { @Override - protected void onCardSelected(Card card, boolean isRmb) { - final SpellAbility ab = player.getController().getAbilityToPlay(card.getAllPossibleAbilities(player)); - if ( null != ab) { + protected void onCardSelected(final Card card, final MouseEvent triggerEvent) { + List abilities = card.getAllPossibleAbilities(player); + if (abilities.isEmpty()) { + flashIncorrectAction(); + return; + } + + selectAbility(player.getController().getAbilityToPlay(abilities, triggerEvent)); + } + + @Override + public void selectAbility(final SpellAbility ab) { + if (ab != null) { chosenSa = ab; stop(); } - else { - flashIncorrectAction(); - } } } diff --git a/forge-gui/src/main/java/forge/gui/input/InputPayMana.java b/forge-gui/src/main/java/forge/gui/input/InputPayMana.java index 5a4ce7721b7..fde15d299ac 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputPayMana.java +++ b/forge-gui/src/main/java/forge/gui/input/InputPayMana.java @@ -1,5 +1,6 @@ package forge.gui.input; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -49,7 +50,7 @@ public abstract class InputPayMana extends InputSyncronizedBase { @Override - protected void onCardSelected(Card card, boolean isRmb) { + protected void onCardSelected(final Card card, final MouseEvent triggerEvent) { if (card.getManaAbility().isEmpty()) { flashIncorrectAction(); return; diff --git a/forge-gui/src/main/java/forge/gui/input/InputPayManaX.java b/forge-gui/src/main/java/forge/gui/input/InputPayManaX.java index 8e0d9f2535b..8a43f8eaa0a 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputPayManaX.java +++ b/forge-gui/src/main/java/forge/gui/input/InputPayManaX.java @@ -1,5 +1,6 @@ package forge.gui.input; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; @@ -81,7 +82,7 @@ public class InputPayManaX extends InputPayMana { } @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 activateManaAbility(card, this.manaCost); } diff --git a/forge-gui/src/main/java/forge/gui/input/InputProliferate.java b/forge-gui/src/main/java/forge/gui/input/InputProliferate.java index d8036925c49..fd8b2fce229 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputProliferate.java +++ b/forge-gui/src/main/java/forge/gui/input/InputProliferate.java @@ -1,5 +1,6 @@ package forge.gui.input; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -41,7 +42,7 @@ public final class InputProliferate extends InputSelectManyBase { } @Override - protected void onCardSelected(Card card, boolean isRmb) { + protected void onCardSelected(final Card card, final MouseEvent triggerEvent) { if( !selectEntity(card) ) return; diff --git a/forge-gui/src/main/java/forge/gui/input/InputSelectCards.java b/forge-gui/src/main/java/forge/gui/input/InputSelectCards.java index b19adab7e49..fcadb2daf37 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputSelectCards.java +++ b/forge-gui/src/main/java/forge/gui/input/InputSelectCards.java @@ -1,5 +1,7 @@ package forge.gui.input; +import java.awt.event.MouseEvent; + import forge.Card; public abstract class InputSelectCards extends InputSelectManyBase { @@ -10,7 +12,7 @@ public abstract class InputSelectCards extends InputSelectManyBase { } @Override - protected void onCardSelected(Card c, boolean isRmb) { + protected void onCardSelected(final Card c, final MouseEvent triggerEvent) { if ( !selectEntity(c) ) return; diff --git a/forge-gui/src/main/java/forge/gui/input/InputSelectTargets.java b/forge-gui/src/main/java/forge/gui/input/InputSelectTargets.java index 5617ff54641..3a910537fb6 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputSelectTargets.java +++ b/forge-gui/src/main/java/forge/gui/input/InputSelectTargets.java @@ -1,5 +1,6 @@ package forge.gui.input; +import java.awt.event.MouseEvent; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -101,7 +102,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { } @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)) { return; } diff --git a/forge-gui/src/main/java/forge/view/arcane/HandArea.java b/forge-gui/src/main/java/forge/view/arcane/HandArea.java index 9df551510ef..d12b2ea71e8 100644 --- a/forge-gui/src/main/java/forge/view/arcane/HandArea.java +++ b/forge-gui/src/main/java/forge/view/arcane/HandArea.java @@ -63,14 +63,14 @@ public class HandArea extends CardArea { /** {@inheritDoc} */ @Override 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); } /** {@inheritDoc} */ @Override 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); } } diff --git a/forge-gui/src/main/java/forge/view/arcane/PlayArea.java b/forge-gui/src/main/java/forge/view/arcane/PlayArea.java index ea3096d7f94..71e3029dcf0 100644 --- a/forge-gui/src/main/java/forge/view/arcane/PlayArea.java +++ b/forge-gui/src/main/java/forge/view/arcane/PlayArea.java @@ -501,7 +501,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen /** {@inheritDoc} */ @Override 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)) { return; } @@ -511,7 +511,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen /** {@inheritDoc} */ @Override 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); }