Merge pull request #2032 from draxdyn/hold_priority

Hold priority on Ctrl+click
This commit is contained in:
LevelX2 2016-07-01 16:00:20 +02:00 committed by GitHub
commit 2874996994
8 changed files with 147 additions and 13 deletions

View file

@ -27,16 +27,20 @@
*/
package mage.client;
import java.awt.AWTEvent;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.SplashScreen;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
@ -225,6 +229,26 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
return instance;
}
private void handleEvent(AWTEvent event) {
MagePane frame = activeFrame;
// support multiple mage panes
Object source = event.getSource();
if(source instanceof Component) {
Component component = (Component)source;
while(component != null) {
if(component instanceof MagePane) {
frame = (MagePane)component;
break;
}
component = component.getParent();
}
}
if(frame != null)
frame.handleEvent(event);
}
/**
* Creates new form MageFrame
*/
@ -240,6 +264,13 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
});
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event) {
handleEvent(event);
}
}, AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
TConfig config = TConfig.current();
config.setArchiveDetector(new TArchiveDetector("zip"));
config.setAccessPreference(FsAccessOption.STORE, true);

View file

@ -33,6 +33,7 @@
*/
package mage.client;
import java.awt.AWTEvent;
import java.awt.KeyboardFocusManager;
import java.beans.PropertyVetoException;
import javax.swing.plaf.basic.BasicInternalFrameUI;
@ -91,6 +92,9 @@ public abstract class MagePane extends javax.swing.JInternalFrame {
}
public void handleEvent(AWTEvent event) {
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always

View file

@ -33,6 +33,7 @@
*/
package mage.client.game;
import java.awt.AWTEvent;
import java.util.UUID;
import javax.swing.SwingUtilities;
import mage.client.MagePane;
@ -132,8 +133,12 @@ public class GamePane extends MagePane {
gamePanel.activated();
}
@Override
public void handleEvent(AWTEvent event) {
gamePanel.handleEvent(event);
}
private mage.client.game.GamePanel gamePanel;
private javax.swing.JScrollPane jScrollPane1;
private UUID gameId;
}

View file

@ -27,6 +27,7 @@
*/
package mage.client.game;
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@ -391,6 +392,7 @@ public final class GamePanel extends javax.swing.JPanel {
stackObjects.setCardDimension(GUISizeHelper.handCardDimension);
txtSpellsCast.setFont(new Font(GUISizeHelper.gameDialogAreaFont.getFontName(), Font.BOLD, GUISizeHelper.gameDialogAreaFont.getSize()));
txtHoldPriority.setFont(new Font(GUISizeHelper.gameDialogAreaFont.getFontName(), Font.BOLD, GUISizeHelper.gameDialogAreaFont.getSize()));
GUISizeHelper.changePopupMenuFont(popupMenuTriggerOrder);
int newStackWidth = pnlHelperHandButtonsStackArea.getWidth() * GUISizeHelper.stackWidth / 100;
@ -589,7 +591,8 @@ public final class GamePanel extends javax.swing.JPanel {
setMenuStates(
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true")
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
holdingPriority
);
updateGame(game);
@ -957,9 +960,9 @@ public final class GamePanel extends javax.swing.JPanel {
* @param manaPoolAutomaticRestricted
* @param useFirstManaAbility
*/
public void setMenuStates(boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted, boolean useFirstManaAbility) {
public void setMenuStates(boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted, boolean useFirstManaAbility, boolean holdPriority) {
for (PlayAreaPanel playAreaPanel : players.values()) {
playAreaPanel.setMenuStates(manaPoolAutomatic, manaPoolAutomaticRestricted, useFirstManaAbility);
playAreaPanel.setMenuStates(manaPoolAutomatic, manaPoolAutomaticRestricted, useFirstManaAbility, holdPriority);
}
}
@ -1201,6 +1204,14 @@ public final class GamePanel extends javax.swing.JPanel {
}
public void select(String message, GameView gameView, int messageId, Map<String, Serializable> options) {
holdingPriority = false;
txtHoldPriority.setVisible(false);
setMenuStates(
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
false);
updateGame(gameView, options);
boolean controllingPlayer = false;
for (PlayerView playerView : gameView.getPlayers()) {
@ -1340,6 +1351,14 @@ public final class GamePanel extends javax.swing.JPanel {
txtSpellsCast.setOpaque(true);
txtSpellsCast.setToolTipText("spells cast during the current turn");
txtHoldPriority = new javax.swing.JLabel();
txtHoldPriority.setText("Hold");
txtHoldPriority.setBorder(BorderFactory.createCompoundBorder(border, paddingBorder));
txtHoldPriority.setBackground(Color.LIGHT_GRAY);
txtHoldPriority.setOpaque(true);
txtHoldPriority.setToolTipText("Holding priority after the next spell cast or ability activation");
txtHoldPriority.setVisible(false);
btnCancelSkip = new javax.swing.JButton(); // F3
btnSkipToNextTurn = new javax.swing.JButton(); // F4
btnSkipToEndTurn = new javax.swing.JButton(); // F5
@ -1670,7 +1689,8 @@ public final class GamePanel extends javax.swing.JPanel {
setMenuStates(
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"));
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
holdingPriority);
}
});
@ -1713,7 +1733,8 @@ public final class GamePanel extends javax.swing.JPanel {
setMenuStates(
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"));
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
holdingPriority);
}
});
@ -1829,6 +1850,7 @@ public final class GamePanel extends javax.swing.JPanel {
.addComponent(btnSkipToEndStepBeforeYourTurn)
)
.addGroup(gl_pnlShortCuts.createSequentialGroup()
.addComponent(txtHoldPriority)
.addComponent(txtSpellsCast)
.addComponent(btnSwitchHands)
.addComponent(btnCancelSkip)
@ -1862,6 +1884,7 @@ public final class GamePanel extends javax.swing.JPanel {
.addComponent(btnSkipToEndStepBeforeYourTurn)
)
.addGroup(gl_pnlShortCuts.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(txtHoldPriority)
.addComponent(txtSpellsCast)
.addComponent(btnSwitchHands)
.addComponent(btnCancelSkip)
@ -2343,6 +2366,48 @@ public final class GamePanel extends javax.swing.JPanel {
return feedbackPanel;
}
// Use Cmd on OSX since Ctrl+click is already used to simulate right click
private static int holdPriorityMask = System.getProperty("os.name").contains("Mac OS X") ? InputEvent.META_DOWN_MASK : InputEvent.CTRL_DOWN_MASK;
public void handleEvent(AWTEvent event) {
if(event instanceof InputEvent) {
int id = event.getID();
boolean isActionEvent = false;
if(id == MouseEvent.MOUSE_PRESSED)
isActionEvent = true;
else if(id == KeyEvent.KEY_PRESSED)
{
KeyEvent key = (KeyEvent)event;
int keyCode = key.getKeyCode();
if(keyCode == KeyEvent.VK_ENTER || keyCode == KeyEvent.VK_SPACE)
isActionEvent = true;
}
if(isActionEvent) {
InputEvent input = (InputEvent)event;
if((input.getModifiersEx() & holdPriorityMask) != 0) {
setMenuStates(
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
true);
holdPriority(true);
}
}
}
}
public void holdPriority(boolean holdPriority) {
if(holdingPriority != holdPriority) {
holdingPriority = holdPriority;
txtHoldPriority.setVisible(holdPriority);
if(holdPriority)
session.sendPlayerAction(PlayerAction.HOLD_PRIORITY, gameId, null);
else
session.sendPlayerAction(PlayerAction.UNHOLD_PRIORITY, gameId, null);
}
}
private boolean holdingPriority;
private mage.client.components.ability.AbilityPicker abilityPicker;
private mage.client.cards.BigCard bigCard;
@ -2397,6 +2462,7 @@ public final class GamePanel extends javax.swing.JPanel {
private JPanel jPhases;
private JPanel phasesContainer;
private javax.swing.JLabel txtSpellsCast;
private javax.swing.JLabel txtHoldPriority;
private HoverButton currentStep;
private Point prevPoint;

View file

@ -78,6 +78,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
private JCheckBoxMenuItem manaPoolMenuItem2;
private JCheckBoxMenuItem useFirstManaAbilityItem;
private JCheckBoxMenuItem allowViewHandCardsMenuItem;
private JCheckBoxMenuItem holdPriorityMenuItem;
public static final int PANEL_HEIGHT = 242;
public static final int PANEL_HEIGHT_SMALL = 190;
@ -210,6 +211,19 @@ public class PlayAreaPanel extends javax.swing.JPanel {
popupMenu.add(menuItem);
menuItem.addActionListener(skipListener);
holdPriorityMenuItem = new JCheckBoxMenuItem("<html><b>" + (System.getProperty("os.name").contains("Mac OS X") ? "Cmd" : "Ctrl") + "+click</b> - Hold Priority");
holdPriorityMenuItem.setMnemonic(KeyEvent.VK_P);
holdPriorityMenuItem.setToolTipText("<html>Hold priority after casting a spell or activating an ability, instead of automatically passing priority.");
popupMenu.add(holdPriorityMenuItem);
holdPriorityMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean holdPriority = ((JCheckBoxMenuItem)e.getSource()).getState();
gamePanel.setMenuStates(manaPoolMenuItem1.getState(), manaPoolMenuItem2.getState(), useFirstManaAbilityItem.getState(), holdPriority);
gamePanel.holdPriority(holdPriority);
}
});
JMenu skipMenu = new JMenu("Skip");
skipMenu.setMnemonic(KeyEvent.VK_S);
popupMenu.add(skipMenu);
@ -277,7 +291,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
public void actionPerformed(ActionEvent e) {
boolean manaPoolAutomatic = ((JCheckBoxMenuItem) e.getSource()).getState();
PreferencesDialog.saveValue(KEY_GAME_MANA_AUTOPAYMENT, manaPoolAutomatic ? "true" : "false");
gamePanel.setMenuStates(manaPoolAutomatic, manaPoolMenuItem2.getState(), useFirstManaAbilityItem.getState());
gamePanel.setMenuStates(manaPoolAutomatic, manaPoolMenuItem2.getState(), useFirstManaAbilityItem.getState(), holdPriorityMenuItem.getState());
gamePanel.getSession().sendPlayerAction(manaPoolAutomatic ? PlayerAction.MANA_AUTO_PAYMENT_ON : PlayerAction.MANA_AUTO_PAYMENT_OFF, gameId, null);
}
});
@ -295,7 +309,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
public void actionPerformed(ActionEvent e) {
boolean manaPoolAutomaticRestricted = ((JCheckBoxMenuItem) e.getSource()).getState();
PreferencesDialog.saveValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, manaPoolAutomaticRestricted ? "true" : "false");
gamePanel.setMenuStates(manaPoolMenuItem1.getState(), manaPoolAutomaticRestricted, useFirstManaAbilityItem.getState());
gamePanel.setMenuStates(manaPoolMenuItem1.getState(), manaPoolAutomaticRestricted, useFirstManaAbilityItem.getState(), holdPriorityMenuItem.getState());
gamePanel.getSession().sendPlayerAction(manaPoolAutomaticRestricted ? PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_ON : PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_OFF, gameId, null);
}
});
@ -313,7 +327,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
public void actionPerformed(ActionEvent e) {
boolean useFirstManaAbility = ((JCheckBoxMenuItem) e.getSource()).getState();
PreferencesDialog.saveValue(KEY_USE_FIRST_MANA_ABILITY, useFirstManaAbility ? "true" : "false");
gamePanel.setMenuStates(manaPoolMenuItem1.getState(), manaPoolMenuItem2.getState(), useFirstManaAbility);
gamePanel.setMenuStates(manaPoolMenuItem1.getState(), manaPoolMenuItem2.getState(), useFirstManaAbility, holdPriorityMenuItem.getState());
gamePanel.getSession().sendPlayerAction(useFirstManaAbility ? PlayerAction.USE_FIRST_MANA_ABILITY_ON: PlayerAction.USE_FIRST_MANA_ABILITY_OFF, gameId, null);
}
});
@ -642,7 +656,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
this.playingMode = playingMode;
}
public void setMenuStates(boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted, boolean useFirstManaAbility) {
public void setMenuStates(boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted, boolean useFirstManaAbility, boolean holdPriority) {
if (manaPoolMenuItem1 != null) {
manaPoolMenuItem1.setSelected(manaPoolAutomatic);
}
@ -652,6 +666,9 @@ public class PlayAreaPanel extends javax.swing.JPanel {
if (useFirstManaAbilityItem != null) {
useFirstManaAbilityItem.setSelected(useFirstManaAbility);
}
if (holdPriorityMenuItem != null) {
holdPriorityMenuItem.setSelected(holdPriority);
}
}
private mage.client.game.BattlefieldPanel battlefieldPanel;

View file

@ -395,7 +395,8 @@ public class CallbackClientImpl implements CallbackClient {
.append("<br/><b>F7</b> - Skip to next main phase but stop on declare attackers/blockers and something on the stack")
.append("<br/><b>F9</b> - Skip everything until your next turn")
.append("<br/><b>F11</b> - Skip everything until the end step just prior to your turn")
.append("<br/><b>F3</b> - Undo F4/F5/F7/F9/F11").toString(),
.append("<br/><b>F3</b> - Undo F4/F5/F7/F9/F11")
.append("<br/><b>").append(System.getProperty("os.name").contains("Mac OS X") ? "Cmd" : "Ctrl").append(" + click</b> - Hold priority while casting a spell or activating an ability").toString(),
null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE);
break;
case TOURNAMENT:

View file

@ -123,6 +123,8 @@ public class HumanPlayer extends PlayerImpl {
protected Map<String, Boolean> requestAutoAnswerId = new HashMap<>();
protected Map<String, Boolean> requestAutoAnswerText = new HashMap<>();
protected boolean holdingPriority;
public HumanPlayer(String name, RangeOfInfluence range, int skill) {
super(name, range);
replacementEffectChoice = new ChoiceImpl(true);
@ -565,7 +567,7 @@ public class HumanPlayer extends PlayerImpl {
public boolean priority(Game game) {
passed = false;
if (!abort) {
if (getJustActivatedType() != null) {
if (getJustActivatedType() != null && !holdingPriority) {
if (userData.isPassPriorityCast() && getJustActivatedType().equals(AbilityType.SPELL)) {
setJustActivatedType(null);
pass(game);
@ -661,6 +663,7 @@ public class HumanPlayer extends PlayerImpl {
}
while (canRespond()) {
updateGameStatePriority("priority", game);
holdingPriority = false;
game.firePriorityEvent(playerId);
waitForResponse(game);
if (game.executingRollback()) {
@ -1465,6 +1468,12 @@ public class HumanPlayer extends PlayerImpl {
case REQUEST_AUTO_ANSWER_RESET_ALL:
setRequestAutoAnswer(playerAction, game, data);
break;
case HOLD_PRIORITY:
holdingPriority = true;
break;
case UNHOLD_PRIORITY:
holdingPriority = false;
break;
default:
super.sendPlayerAction(playerAction, game, data);
}

View file

@ -82,5 +82,6 @@ public enum PlayerAction {
CLIENT_DOWNLOAD_CARD_IMAGES,
CLIENT_RECONNECT,
CLIENT_REPLAY_ACTION,
HOLD_PRIORITY,
UNHOLD_PRIORITY
}