* Added button popup menu to be able to automatically answer ability related "Yes" / "No" requests (related to #328).

This commit is contained in:
LevelX2 2015-08-28 11:44:14 +02:00
parent faac815ed2
commit 758f56792e
17 changed files with 555 additions and 184 deletions

View file

@ -47,7 +47,9 @@ import mage.client.components.MageTextArea;
import mage.client.dialog.MageDialog;
import mage.client.util.audio.AudioManager;
import mage.client.util.gui.ArrowBuilder;
import mage.constants.Constants;
import static mage.constants.Constants.Option.ORIGINAL_ID;
import static mage.constants.Constants.Option.SECOND_MESSAGE;
import static mage.constants.Constants.Option.SPECIAL_BUTTON;
import mage.constants.PlayerAction;
import mage.remote.Session;
import org.apache.log4j.Logger;
@ -85,6 +87,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
public void init(UUID gameId) {
this.gameId = gameId;
session = MageFrame.getSession();
helper.init(gameId);
}
public void getFeedback(FeedbackMode mode, String message, boolean special, Map<String, Serializable> options, int messageId) {
@ -95,61 +98,42 @@ public class FeedbackPanel extends javax.swing.JPanel {
}
this.lastMessageId = messageId;
}
this.lblMessage.setText(message);
this.helper.setMessage(message);
this.helper.setBasicMessage(message);
this.helper.setOriginalId(null); // reference to the feedback causing ability
String lblText = addAdditionalText(message, options);
this.helper.setTextArea(lblText);
this.lblMessage.setText(lblText);
this.mode = mode;
switch (this.mode) {
case INFORM:
this.btnLeft.setVisible(false);
this.btnRight.setVisible(false);
this.helper.setState("", false, "", false);
setButtonState("", "", mode);
break;
case QUESTION:
this.btnLeft.setVisible(true);
this.btnLeft.setText("Yes");
this.btnRight.setVisible(true);
this.btnRight.setText("No");
this.helper.setState("Yes", true, "No", true);
setButtonState("Yes", "No", mode);
if (options != null && options.containsKey(ORIGINAL_ID)) {
this.helper.setOriginalId((UUID) options.get(ORIGINAL_ID));
}
break;
case CONFIRM:
this.btnLeft.setVisible(true);
this.btnLeft.setText("OK");
this.btnRight.setVisible(true);
this.btnRight.setText("Cancel");
this.helper.setState("Ok", true, "Cancel", true);
setButtonState("OK", "Cancel", mode);
break;
case CANCEL:
this.btnLeft.setVisible(false);
this.btnRight.setVisible(true);
this.btnRight.setText("Cancel");
this.helper.setState("", false, "Cancel", true);
setButtonState("", "Cancel", mode);
this.helper.setUndoEnabled(false);
break;
case SELECT:
this.btnLeft.setVisible(false);
this.btnRight.setVisible(true);
this.btnRight.setText("Done");
this.helper.setState("", false, "Done", true);
setButtonState("", "Done", mode);
break;
case END:
this.btnLeft.setVisible(false);
this.btnRight.setVisible(true);
this.btnRight.setText("Close game");
this.helper.setState("", false, "Close game", true);
setButtonState("", "Close game", mode);
ArrowBuilder.getBuilder().removeAllArrows(gameId);
endWithTimeout();
break;
}
if (options != null && options.containsKey(Constants.Option.SPECIAL_BUTTON)) {
String specialText = (String) options.get(Constants.Option.SPECIAL_BUTTON);
this.btnSpecial.setVisible(true);
this.btnSpecial.setText(specialText);
this.helper.setSpecial(specialText, true);
if (options != null && options.containsKey(SPECIAL_BUTTON)) {
this.setSpecial((String) options.get(SPECIAL_BUTTON), true);
} else {
this.btnSpecial.setVisible(special);
this.btnSpecial.setText("Special");
this.helper.setSpecial("Special", special);
this.setSpecial("Special", special);
}
requestFocusIfPossible();
@ -162,6 +146,32 @@ public class FeedbackPanel extends javax.swing.JPanel {
this.helper.setVisible(true);
}
private void setButtonState(String leftText, String rightText, FeedbackMode mode) {
btnLeft.setVisible(!leftText.isEmpty());
btnLeft.setText(leftText);
btnRight.setVisible(!rightText.isEmpty());
btnRight.setText(rightText);
this.helper.setState(leftText, !leftText.isEmpty(), rightText, !rightText.isEmpty(), mode);
}
private String addAdditionalText(String message, Map<String, Serializable> options) {
if (options != null && options.containsKey(SECOND_MESSAGE)) {
return message + getSmallText((String) options.get(SECOND_MESSAGE));
} else {
return message;
}
}
protected String getSmallText(String text) {
return "<div style='font-size:11pt'>" + text + "</div>";
}
private void setSpecial(String text, boolean visible) {
this.btnSpecial.setText(text);
this.btnSpecial.setVisible(visible);
this.helper.setSpecial(text, visible);
}
/**
* Close game window by pressing OK button after 8 seconds
*/

View file

@ -28,17 +28,34 @@
package mage.client.game;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.UUID;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import mage.client.MageFrame;
import mage.client.components.MageTextArea;
import mage.client.game.FeedbackPanel.FeedbackMode;
import static mage.client.game.FeedbackPanel.FeedbackMode.QUESTION;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_ID_NO;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_ID_YES;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_TEXT_NO;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_TEXT_YES;
import mage.remote.Session;
/**
* Panel with buttons that copy the state of feedback panel.
@ -64,12 +81,34 @@ public class HelperPanel extends JPanel {
private final int defaultDismissTimeout = ToolTipManager.sharedInstance().getDismissDelay();
private final Object tooltipBackground = UIManager.get("info");
private static final String CMD_AUTO_ANSWER_ID_YES = "cmdAutoAnswerIdYes";
private static final String CMD_AUTO_ANSWER_ID_NO = "cmdAutoAnswerIdNo";
private static final String CMD_AUTO_ANSWER_NAME_YES = "cmdAutoAnswerNameYes";
private static final String CMD_AUTO_ANSWER_NAME_NO = "cmdAutoAnswerNameNo";
private static final String CMD_AUTO_ANSWER_RESET_ALL = "cmdAutoAnswerResetAll";
// popup menu for set automatic answers
private JPopupMenu popupMenuAskYes;
private JPopupMenu popupMenuAskNo;
// originalId of feedback causing ability
private UUID originalId;
private String message;
private UUID gameId;
private Session session;
public HelperPanel() {
initComponents();
}
private void initComponents() {
public void init(UUID gameId) {
this.gameId = gameId;
session = MageFrame.getSession();
}
private void initComponents() {
initPopupMenuTriggerOrder();
setBackground(new Color(0, 0, 0, 100));
//setLayout(new GridBagLayout());
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
@ -108,71 +147,49 @@ public class HelperPanel extends JPanel {
btnUndo.setVisible(false);
container.add(btnUndo);
btnLeft.addActionListener(new java.awt.event.ActionListener() {
MouseListener checkPopupAdapter = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent me) {
checkPopupMenu(me);
}
@Override
public void mouseReleased(MouseEvent me) {
checkPopupMenu(me);
}
};
btnLeft.addMouseListener(checkPopupAdapter);
btnLeft.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkLeft != null) {
{
Thread worker = new Thread() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setState("", false, "", false);
setSpecial("", false);
linkLeft.doClick();
}
});
}
};
worker.start();
}
clickButton(linkLeft);
}
}
});
btnRight.addActionListener(new java.awt.event.ActionListener() {
btnRight.addMouseListener(checkPopupAdapter);
btnRight.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkRight != null) {
Thread worker = new Thread() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setState("", false, "", false);
setSpecial("", false);
linkRight.doClick();
}
});
}
};
worker.start();
clickButton(linkRight);
}
}
});
btnSpecial.addActionListener(new java.awt.event.ActionListener() {
btnSpecial.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkSpecial != null) {
{
Thread worker = new Thread() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setState("", false, "", false);
setSpecial("", false);
linkSpecial.doClick();
}
});
}
};
worker.start();
// if (evt.getActionCommand().equals("automatic")) {
// showPopupMenu(evt);
// } else {
clickButton(linkSpecial);
// }
}
}
}
@ -200,7 +217,7 @@ public class HelperPanel extends JPanel {
}
});
// sets a darker background and higher simiss time fpr tooltip in the feedback / helper panel
// sets a darker background and higher simiss time fur tooltip in the feedback / helper panel
textArea.addMouseListener(new MouseAdapter() {
@Override
@ -217,15 +234,50 @@ public class HelperPanel extends JPanel {
});
}
public void setState(String txtLeft, boolean leftVisible, String txtRight, boolean rightVisible) {
private void checkPopupMenu(MouseEvent me) {
if (me.isPopupTrigger()
&& originalId != null) { // only Yes/No requests from abilities can be automated
JButton source = (JButton) me.getSource();
if (source.getActionCommand().startsWith(QUESTION.toString())) {
showPopupMenu(me.getComponent(), source.getActionCommand());
me.consume();
}
}
}
private void clickButton(final JButton button) {
Thread worker = new Thread() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setState("", false, "", false, null);
setSpecial("", false);
button.doClick();
}
});
}
};
worker.start();
}
public void setState(String txtLeft, boolean leftVisible, String txtRight, boolean rightVisible, FeedbackMode mode) {
this.btnLeft.setVisible(leftVisible);
if (!txtLeft.isEmpty()) {
this.btnLeft.setText(txtLeft);
if (mode != null) {
this.btnLeft.setActionCommand(mode.toString() + txtLeft);
}
}
this.btnRight.setVisible(rightVisible);
if (!txtRight.isEmpty()) {
this.btnRight.setText(txtRight);
if (mode != null) {
this.btnRight.setActionCommand(mode.toString() + txtRight);
}
}
}
public void setSpecial(String txtSpecial, boolean specialVisible) {
@ -251,25 +303,116 @@ public class HelperPanel extends JPanel {
this.linkUndo = undo;
}
public void setMessage(String message) {
// if (message.startsWith("Use alternative cost")) {
// message = "Use alternative cost?";
// } else if (message.contains("Use ")) {
// if (message.length() < this.getWidth() / 10) {
// message = getSmallText(message);
// } else {
// message = "Use ability?" + getSmallText(message.substring(0, this.getWidth() / 10));
// }
// }
textArea.setText(message, this.getWidth());
public void setOriginalId(UUID originalId) {
this.originalId = originalId;
}
protected String getSmallText(String text) {
return "<div style='font-size:11pt'>" + text + "</div>";
public void setBasicMessage(String message) {
this.message = message;
this.textArea.setText(message, this.getWidth());
}
public void setTextArea(String message) {
this.textArea.setText(message, this.getWidth());
}
@Override
public void requestFocus() {
this.btnRight.requestFocus();
}
private void initPopupMenuTriggerOrder() {
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
handleAutoAnswerPopupMenuEvent(e);
}
};
popupMenuAskYes = new JPopupMenu();
popupMenuAskNo = new JPopupMenu();
// String tooltipText = "";
JMenuItem menuItem;
menuItem = new JMenuItem("Always Yes for the same text and ability");
menuItem.setActionCommand(CMD_AUTO_ANSWER_ID_YES);
menuItem.addActionListener(actionListener);
menuItem.setToolTipText("<HTML>If the same question from the same ability would<br/>be asked again, it's automatically answered with <b>Yes</b>.");
popupMenuAskYes.add(menuItem);
menuItem = new JMenuItem("Always No for the same text and ability");
menuItem.setActionCommand(CMD_AUTO_ANSWER_ID_NO);
menuItem.setToolTipText("<HTML>If the same question from the same ability would<br/>be asked again, it's automatically answered with <b>No</b>.");
menuItem.addActionListener(actionListener);
popupMenuAskNo.add(menuItem);
menuItem = new JMenuItem("Always Yes for the same text");
menuItem.setActionCommand(CMD_AUTO_ANSWER_NAME_YES);
menuItem.setToolTipText("<HTML>If the same question would be asked again (regardless from which source),<br/> it's automatically answered with <b>Yes</b>.");
menuItem.addActionListener(actionListener);
popupMenuAskYes.add(menuItem);
menuItem = new JMenuItem("Always No for the same text");
menuItem.setActionCommand(CMD_AUTO_ANSWER_NAME_NO);
menuItem.setToolTipText("<HTML>If the same question would be asked again (regardless from which source),<br/> it's automatically answered with <b>No</b>.");
menuItem.addActionListener(actionListener);
popupMenuAskNo.add(menuItem);
menuItem = new JMenuItem("Delete all automatic Yes/No settings");
menuItem.setActionCommand(CMD_AUTO_ANSWER_RESET_ALL);
menuItem.addActionListener(actionListener);
popupMenuAskYes.add(menuItem);
menuItem = new JMenuItem("Delete all automatic Yes/No settings");
menuItem.setActionCommand(CMD_AUTO_ANSWER_RESET_ALL);
menuItem.addActionListener(actionListener);
popupMenuAskNo.add(menuItem);
}
public void handleAutoAnswerPopupMenuEvent(ActionEvent e) {
switch (e.getActionCommand()) {
case CMD_AUTO_ANSWER_ID_YES:
session.sendPlayerAction(REQUEST_AUTO_ANSWER_ID_YES, gameId, originalId.toString() + "#" + message);
clickButton(btnLeft);
break;
case CMD_AUTO_ANSWER_ID_NO:
session.sendPlayerAction(REQUEST_AUTO_ANSWER_ID_NO, gameId, originalId.toString() + "#" + message);
clickButton(btnRight);
break;
case CMD_AUTO_ANSWER_NAME_YES:
session.sendPlayerAction(REQUEST_AUTO_ANSWER_TEXT_YES, gameId, message);
clickButton(btnLeft);
break;
case CMD_AUTO_ANSWER_NAME_NO:
session.sendPlayerAction(REQUEST_AUTO_ANSWER_TEXT_NO, gameId, message);
clickButton(btnRight);
break;
case CMD_AUTO_ANSWER_RESET_ALL:
session.sendPlayerAction(REQUEST_AUTO_ANSWER_RESET_ALL, gameId, null);
break;
}
}
private void showPopupMenu(Component callingComponent, String actionCommand) {
// Get the location of the point 'on the screen'
Point p = callingComponent.getLocationOnScreen();
// Show the JPopupMenu via program
// Parameter desc
// ----------------
// this - represents current frame
// 0,0 is the co ordinate where the popup
// is shown
JPopupMenu menu;
if (actionCommand.endsWith("Yes")) {
menu = popupMenuAskYes;
} else {
menu = popupMenuAskNo;
}
menu.show(this, 0, 0);
// Now set the location of the JPopupMenu
// This location is relative to the screen
menu.setLocation(p.x, p.y + callingComponent.getHeight());
}
}

View file

@ -290,6 +290,18 @@ public class PlayAreaPanel extends javax.swing.JPanel {
}
});
menuItem = new JMenuItem("Use requests - reset automatic answers");
menuItem.setMnemonic(KeyEvent.VK_T);
menuItem.setToolTipText("Deletes all defined automatic answers for Yes/No usage requests.");
automaticConfirmsMenu.add(menuItem);
// Reset the replacement effcts that were auto selected for the game
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.getSession().sendPlayerAction(PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL, gameId, null);
}
});
JMenu handCardsMenu = new JMenu("Cards on hand");
handCardsMenu.setMnemonic(KeyEvent.VK_H);
popupMenu.add(handCardsMenu);