/* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ package mage.client.game; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridLayout; 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.JButton; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.ScrollPaneConstants; import javax.swing.SwingUtilities; import javax.swing.ToolTipManager; import javax.swing.UIManager; import mage.client.SessionHandler; import mage.client.components.MageTextArea; import mage.client.game.FeedbackPanel.FeedbackMode; import static mage.client.game.FeedbackPanel.FeedbackMode.QUESTION; import mage.client.util.GUISizeHelper; 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; /** * Panel with buttons that copy the state of feedback panel. * * @author ayrat */ public class HelperPanel extends JPanel { private javax.swing.JButton btnLeft; private javax.swing.JButton btnRight; private javax.swing.JButton btnSpecial; private javax.swing.JButton btnUndo; //private javax.swing.JButton btnEndTurn; //private javax.swing.JButton btnStopTimer; private JScrollPane textAreaScrollPane; private MageTextArea dialogTextArea; JPanel buttonContainer; private javax.swing.JButton linkLeft; private javax.swing.JButton linkRight; private javax.swing.JButton linkSpecial; private javax.swing.JButton linkUndo; 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; public HelperPanel() { initComponents(); } public void init(UUID gameId) { this.gameId = gameId; } public void changeGUISize() { setGUISize(); } private void setGUISize() { //this.setMaximumSize(new Dimension(getParent().getWidth(), Integer.MAX_VALUE)); textAreaScrollPane.setMaximumSize(new Dimension(getParent().getWidth(), GUISizeHelper.gameDialogAreaTextHeight)); textAreaScrollPane.setPreferredSize(new Dimension(getParent().getWidth(), GUISizeHelper.gameDialogAreaTextHeight)); // dialogTextArea.setMaximumSize(new Dimension(getParent().getWidth(), Integer.MAX_VALUE)); // dialogTextArea.setPreferredSize(new Dimension(getParent().getWidth(), GUISizeHelper.gameDialogAreaTextHeight)); // buttonContainer.setPreferredSize(new Dimension(getParent().getWidth(), GUISizeHelper.gameDialogButtonHeight + 4)); // buttonContainer.setMinimumSize(new Dimension(160, GUISizeHelper.gameDialogButtonHeight + 20)); // buttonContainer.setMaximumSize(new Dimension(Integer.MAX_VALUE, GUISizeHelper.gameDialogButtonHeight + 4)); btnLeft.setFont(GUISizeHelper.gameDialogAreaFont); btnRight.setFont(GUISizeHelper.gameDialogAreaFont); btnSpecial.setFont(GUISizeHelper.gameDialogAreaFont); btnUndo.setFont(GUISizeHelper.gameDialogAreaFont); if (message != null) { int pos = this.message.indexOf("font-size:"); if (pos > 0) { String newMessage = this.message.substring(0, pos + 10) + GUISizeHelper.gameDialogAreaFontSizeBig + this.message.substring(pos + 12); pos = this.message.indexOf("font-size:", pos + 10); if (pos > 0) { newMessage = this.message.substring(0, pos + 10) + GUISizeHelper.gameDialogAreaFontSizeSmall + this.message.substring(pos + 12); } setBasicMessage(newMessage); } } GUISizeHelper.changePopupMenuFont(popupMenuAskNo); GUISizeHelper.changePopupMenuFont(popupMenuAskYes); revalidate(); repaint(); } private void initComponents() { initPopupMenuTriggerOrder(); setBackground(new Color(0, 0, 0, 100)); setLayout(new GridLayout(0, 1)); setOpaque(false); dialogTextArea = new MageTextArea(); dialogTextArea.setText("<Empty>"); dialogTextArea.setOpaque(false); textAreaScrollPane = new JScrollPane(dialogTextArea, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); textAreaScrollPane.setOpaque(false); textAreaScrollPane.setBackground(new Color(0, 0, 0, 0)); textAreaScrollPane.getViewport().setOpaque(false); textAreaScrollPane.setBorder(null); textAreaScrollPane.setViewportBorder(null); add(textAreaScrollPane); buttonContainer = new JPanel(); buttonContainer.setLayout(new FlowLayout(FlowLayout.CENTER, 15, 0)); buttonContainer.setOpaque(false); add(buttonContainer); btnSpecial = new JButton("Special"); btnSpecial.setVisible(false); buttonContainer.add(btnSpecial); btnLeft = new JButton("OK"); btnLeft.setVisible(false); buttonContainer.add(btnLeft); btnRight = new JButton("Cancel"); btnRight.setVisible(false); buttonContainer.add(btnRight); btnUndo = new JButton("Undo"); btnUndo.setVisible(false); buttonContainer.add(btnUndo); 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(evt -> { if (linkLeft != null) { clickButton(linkLeft); } }); btnRight.addMouseListener(checkPopupAdapter); btnRight.addActionListener(evt -> { if (linkRight != null) { clickButton(linkRight); } }); btnSpecial.addActionListener(evt -> { if (linkSpecial != null) { clickButton(linkSpecial); } }); btnUndo.addActionListener(evt -> { if (linkUndo != null) { { Thread worker = new Thread(() -> SwingUtilities.invokeLater(() -> linkUndo.doClick())); worker.start(); } } }); // sets a darker background and higher simiss time fur tooltip in the feedback / helper panel dialogTextArea.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent me) { ToolTipManager.sharedInstance().setDismissDelay(100000); UIManager.put("info", Color.DARK_GRAY); } @Override public void mouseExited(MouseEvent me) { ToolTipManager.sharedInstance().setDismissDelay(defaultDismissTimeout); UIManager.put("info", tooltipBackground); } }); } 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(() -> SwingUtilities.invokeLater(() -> { 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) { this.btnSpecial.setVisible(specialVisible); this.btnSpecial.setText(txtSpecial); } public void setUndoEnabled(boolean enabled) { this.btnUndo.setVisible(enabled); } public void setLeft(String text, boolean visible) { this.btnLeft.setVisible(visible); if (!text.isEmpty()) { this.btnLeft.setText(text); } } public void setRight(String txtRight, boolean rightVisible) { this.btnRight.setVisible(rightVisible); if (!txtRight.isEmpty()) { this.btnRight.setText(txtRight); } } public void setLinks(JButton left, JButton right, JButton special, JButton undo) { this.linkLeft = left; this.linkRight = right; this.linkSpecial = special; this.linkUndo = undo; } public void setOriginalId(UUID originalId) { this.originalId = originalId; } public void setBasicMessage(String message) { this.message = message; this.dialogTextArea.setText(message, this.getWidth()); } public void setTextArea(String message) { this.dialogTextArea.setText(message, this.getWidth()); } @Override public void requestFocus() { this.btnRight.requestFocus(); } private void initPopupMenuTriggerOrder() { ActionListener actionListener = 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: SessionHandler.sendPlayerAction(REQUEST_AUTO_ANSWER_ID_YES, gameId, originalId.toString() + '#' + message); clickButton(btnLeft); break; case CMD_AUTO_ANSWER_ID_NO: SessionHandler.sendPlayerAction(REQUEST_AUTO_ANSWER_ID_NO, gameId, originalId.toString() + '#' + message); clickButton(btnRight); break; case CMD_AUTO_ANSWER_NAME_YES: SessionHandler.sendPlayerAction(REQUEST_AUTO_ANSWER_TEXT_YES, gameId, message); clickButton(btnLeft); break; case CMD_AUTO_ANSWER_NAME_NO: SessionHandler.sendPlayerAction(REQUEST_AUTO_ANSWER_TEXT_NO, gameId, message); clickButton(btnRight); break; case CMD_AUTO_ANSWER_RESET_ALL: SessionHandler.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()); } }