GUI: improved feedback needed sound notifications (plays only for inactive game or app, see #6853);

This commit is contained in:
Oleg Agafonov 2020-07-31 20:00:36 +04:00
parent c343767e8e
commit 610baac6ab
6 changed files with 828 additions and 804 deletions

View file

@ -1639,6 +1639,13 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
whatsNewDialog.checkUpdatesAndShow(forceToShowPage);
}
}
public boolean isGameFrameActive(UUID gameId) {
if (activeFrame != null && activeFrame instanceof GamePane) {
return ((GamePane) activeFrame).getGameId().equals(gameId);
}
return false;
}
}
class MagePaneMenuItem extends JCheckBoxMenuItem {

File diff suppressed because it is too large Load diff

View file

@ -1,19 +1,5 @@
/*
* FeedbackPanel.java
*
* Created on 23-Dec-2009, 9:54:01 PM
*/
package mage.client.game;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.chat.ChatPanelBasic;
@ -21,15 +7,22 @@ import mage.client.dialog.MageDialog;
import mage.client.util.GUISizeHelper;
import mage.client.util.audio.AudioManager;
import mage.client.util.gui.ArrowBuilder;
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.constants.TurnPhase;
import org.apache.log4j.Logger;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.Serializable;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static mage.constants.Constants.Option.*;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class FeedbackPanel extends javax.swing.JPanel {
@ -45,7 +38,6 @@ public class FeedbackPanel extends javax.swing.JPanel {
private MageDialog connectedDialog;
private ChatPanelBasic connectedChatPanel;
private int lastMessageId;
private LocalDateTime lastResponse;
private static final ScheduledExecutorService WORKER = Executors.newSingleThreadScheduledExecutor();
@ -86,12 +78,6 @@ public class FeedbackPanel extends javax.swing.JPanel {
this.helper.setTextArea(lblText);
//this.lblMessage.setText(lblText);
// Alert user when needing feedback if last dialog was informative, and it has been over 2 seconds since last input
if (this.mode == FeedbackMode.INFORM && mode != FeedbackMode.INFORM
&& (this.lastResponse == null || this.lastResponse.isBefore(LocalDateTime.now().minusSeconds(2)))) {
AudioManager.playFeedbackNeeded();
}
this.mode = mode;
switch (this.mode) {
case INFORM:
@ -251,7 +237,6 @@ public class FeedbackPanel extends javax.swing.JPanel {
}
private void btnRightActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRightActionPerformed
setLastResponse();
if (connectedDialog != null) {
connectedDialog.removeDialog();
connectedDialog = null;
@ -270,18 +255,15 @@ public class FeedbackPanel extends javax.swing.JPanel {
}//GEN-LAST:event_btnRightActionPerformed
private void btnLeftActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLeftActionPerformed
setLastResponse();
SessionHandler.sendPlayerBoolean(gameId, true);
AudioManager.playButtonCancel();
}//GEN-LAST:event_btnLeftActionPerformed
private void btnSpecialActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSpecialActionPerformed
setLastResponse();
SessionHandler.sendPlayerString(gameId, "special");
}//GEN-LAST:event_btnSpecialActionPerformed
private void btnUndoActionPerformed(java.awt.event.ActionEvent evt) {
setLastResponse();
SessionHandler.sendPlayerAction(PlayerAction.UNDO, gameId, null);
}
@ -313,10 +295,6 @@ public class FeedbackPanel extends javax.swing.JPanel {
this.helper.setUndoEnabled(false);
}
public void setLastResponse() {
this.lastResponse = LocalDateTime.now();
}
private javax.swing.JButton btnLeft;
private javax.swing.JButton btnRight;
private javax.swing.JButton btnSpecial;

View file

@ -18,7 +18,6 @@ import mage.client.dialog.CardInfoWindowDialog.ShowType;
import mage.client.game.FeedbackPanel.FeedbackMode;
import mage.client.plugins.adapters.MageActionCallback;
import mage.client.plugins.impl.Plugins;
import mage.client.themes.ThemeType;
import mage.client.util.Event;
import mage.client.util.*;
import mage.client.util.audio.AudioManager;
@ -1611,7 +1610,7 @@ public final class GamePanel extends javax.swing.JPanel {
txtHoldPriority.setVisible(false);
boolean displayButtonText = PreferencesDialog.getCurrentTheme().isShortcutsVisibleForSkipButtons();
btnToggleMacro = new KeyboundButton(KEY_CONTROL_TOGGLE_MACRO, displayButtonText);
btnCancelSkip = new KeyboundButton(KEY_CONTROL_CANCEL_SKIP, displayButtonText); // F3
btnSkipToNextTurn = new KeyboundButton(KEY_CONTROL_NEXT_TURN, displayButtonText); // F4
@ -2355,7 +2354,6 @@ public final class GamePanel extends javax.swing.JPanel {
}
private void btnEndTurnActionPerformed(java.awt.event.ActionEvent evt) {
this.feedbackPanel.setLastResponse();
SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN, gameId, null);
skipButtons.activateSkipButton(KEY_CONTROL_NEXT_TURN);
@ -2379,7 +2377,6 @@ public final class GamePanel extends javax.swing.JPanel {
}
private void btnUntilEndOfTurnActionPerformed(java.awt.event.ActionEvent evt) {
this.feedbackPanel.setLastResponse();
SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_TURN_END_STEP, gameId, null);
skipButtons.activateSkipButton(KEY_CONTROL_END_STEP);
@ -2397,7 +2394,6 @@ public final class GamePanel extends javax.swing.JPanel {
}
private void btnUntilNextMainPhaseActionPerformed(java.awt.event.ActionEvent evt) {
this.feedbackPanel.setLastResponse();
SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE, gameId, null);
skipButtons.activateSkipButton(KEY_CONTROL_MAIN_STEP);
@ -2406,7 +2402,6 @@ public final class GamePanel extends javax.swing.JPanel {
}
private void btnPassPriorityUntilNextYourTurnActionPerformed(java.awt.event.ActionEvent evt) {
this.feedbackPanel.setLastResponse();
SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_MY_NEXT_TURN, gameId, null);
skipButtons.activateSkipButton(KEY_CONTROL_YOUR_TURN);
@ -2415,7 +2410,6 @@ public final class GamePanel extends javax.swing.JPanel {
}
private void btnPassPriorityUntilStackResolvedActionPerformed(java.awt.event.ActionEvent evt) {
this.feedbackPanel.setLastResponse();
SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_STACK_RESOLVED, gameId, null);
skipButtons.activateSkipButton(KEY_CONTROL_SKIP_STACK);
@ -2424,7 +2418,6 @@ public final class GamePanel extends javax.swing.JPanel {
}
private void btnSkipToEndStepBeforeYourTurnActionPerformed(java.awt.event.ActionEvent evt) {
this.feedbackPanel.setLastResponse();
SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_END_STEP_BEFORE_MY_NEXT_TURN, gameId, null);
skipButtons.activateSkipButton(KEY_CONTROL_PRIOR_END);
@ -2433,7 +2426,6 @@ public final class GamePanel extends javax.swing.JPanel {
}
private void restorePriorityActionPerformed(java.awt.event.ActionEvent evt) {
this.feedbackPanel.setLastResponse();
SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, gameId, null);
skipButtons.activateSkipButton("");

View file

@ -1,4 +1,3 @@
package mage.client.game;
import mage.client.SessionHandler;
@ -6,7 +5,9 @@ import mage.client.components.MageTextArea;
import mage.client.constants.Constants;
import mage.client.dialog.PreferencesDialog;
import mage.client.game.FeedbackPanel.FeedbackMode;
import mage.client.util.AppUtil;
import mage.client.util.GUISizeHelper;
import mage.client.util.audio.AudioManager;
import mage.constants.TurnPhase;
import javax.swing.*;
@ -64,6 +65,18 @@ public class HelperPanel extends JPanel {
private boolean gameNeedFeedback = false;
private TurnPhase gameTurnPhase = null;
private Timer needFeedbackTimer;
{
// start timer to inform user about needed feedback (example: inform by sound play)
needFeedbackTimer = new Timer(100, evt -> SwingUtilities.invokeLater(() -> {
needFeedbackTimer.stop();
if (!AppUtil.isAppActive() || !AppUtil.isGameActive(this.gameId)) {
AudioManager.playFeedbackNeeded();
}
}));
}
public HelperPanel() {
initComponents();
}
@ -297,7 +310,7 @@ public class HelperPanel extends JPanel {
public void autoSizeButtonsAndFeedbackState() {
// two mode: same size for small texts (flow), different size for long texts (grid)
// plus colorize feedback panel on player's priority
// also colorize feedback panel on player's priority and enable sound notification
int BUTTONS_H_GAP = 15;
Color ACTIVE_FEEDBACK_BACKGROUND_COLOR_MAIN = new Color(0, 0, 255, 50);
@ -325,6 +338,10 @@ public class HelperPanel extends JPanel {
// color panel on player's feedback waiting
if (this.gameNeedFeedback) {
// start notification sound timer
this.needFeedbackTimer.restart();
// wait player's action
switch (FEEDBACK_COLORIZING_MODE) {
case Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_DISABLE:
@ -362,6 +379,9 @@ public class HelperPanel extends JPanel {
break;
}
} else {
// stop notification sound timer
this.needFeedbackTimer.stop();
// inform about other players
this.mainPanel.setOpaque(false);
}

View file

@ -0,0 +1,28 @@
package mage.client.util;
import mage.client.MageFrame;
import java.util.UUID;
/**
* @author JayDi85
*/
public class AppUtil {
/**
* Application is active in operation system (got user focus)
*/
public static boolean isAppActive() {
return MageFrame.getInstance().isActive();
}
/**
* Current active panel is game panel (e.g. the user sees the checking game)
*
* @param gameId game to check
* @return
*/
public static boolean isGameActive(UUID gameId) {
return MageFrame.getInstance().isGameFrameActive(gameId);
}
}