From 872ced4344aefc667152b8ff8b2fc704330ab3fc Mon Sep 17 00:00:00 2001 From: magenoxx Date: Mon, 16 Jul 2012 20:23:56 +0400 Subject: [PATCH] [UI] Tray menu. Blinking on new players added to table. Added window restore on double-click. --- .../src/main/java/mage/client/MageFrame.java | 19 ++- .../mage/client/components/tray/MageTray.java | 160 ++++++++++++++++++ .../java/mage/client/dialog/MageDialog.java | 4 + .../client/dialog/TableWaitingDialog.java | 44 ++++- .../src/main/resources/icon-mage-flashed.png | Bin 0 -> 3895 bytes 5 files changed, 213 insertions(+), 14 deletions(-) create mode 100644 Mage.Client/src/main/java/mage/client/components/tray/MageTray.java create mode 100644 Mage.Client/src/main/resources/icon-mage-flashed.png diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 7c363da33f..4851b7699e 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -100,6 +100,8 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { private final static String liteModeArg = "-lite"; private final static String grayModeArg = "-gray"; + private static MageFrame instance; + private static Session session; private ConnectDialog connectDialog; private ErrorDialog errorDialog; @@ -152,6 +154,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { return version; } + public static MageFrame getInstance() { + return instance; + } + /** * Creates new form MageFrame */ @@ -469,14 +475,14 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { } } - private void btnImagesActionPerformed(java.awt.event.ActionEvent evt) { + public void btnImagesActionPerformed(java.awt.event.ActionEvent evt) { HashSet cards = new HashSet(CardsStorage.getAllCards()); List notImplemented = CardsStorage.getNotImplementedCards(); cards.addAll(notImplemented); Plugins.getInstance().downloadImage(cards); } - private void btnSymbolsActionPerformed(java.awt.event.ActionEvent evt) { + public void btnSymbolsActionPerformed(java.awt.event.ActionEvent evt) { if (JOptionPane.showConfirmDialog(null, "Do you want to download mana symbols?") == JOptionPane.OK_OPTION) { Plugins.getInstance().downloadSymbols(); } @@ -818,7 +824,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { } }//GEN-LAST:event_btnConnectActionPerformed - private void btnAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAboutActionPerformed + public void btnAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAboutActionPerformed AboutDialog aboutDialog = new AboutDialog(); desktopPane.add(aboutDialog, JLayeredPane.POPUP_LAYER); aboutDialog.showDialog(version); @@ -828,11 +834,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { showCollectionViewer(); }//GEN-LAST:event_btnCollectionViewerActionPerformed - private void btnPreferencesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPreferencesActionPerformed + public void btnPreferencesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPreferencesActionPerformed PreferencesDialog.main(new String[]{}); }//GEN-LAST:event_btnPreferencesActionPerformed - private void btnSendFeedbackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSendFeedbackActionPerformed + public void btnSendFeedbackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSendFeedbackActionPerformed if (!session.isConnected()) { JOptionPane.showMessageDialog(null, "You may send us feedback only when connected to server.", "Information", JOptionPane.INFORMATION_MESSAGE); return; @@ -982,7 +988,8 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { splash.update(); } } - new MageFrame().setVisible(true); + instance = new MageFrame(); + instance.setVisible(true); } }); } diff --git a/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java b/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java new file mode 100644 index 0000000000..9bc0004db8 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java @@ -0,0 +1,160 @@ +package mage.client.components.tray; + +import mage.client.MageFrame; +import org.apache.log4j.Logger; +import org.mage.plugins.card.utils.impl.ImageManagerImpl; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author noxx + */ +public class MageTray { + + private static final MageTray instance = new MageTray(); + + private static final Logger log = Logger.getLogger(MageTray.class); + + private Image mainImage; + private Image flashedImage; + private TrayIcon trayIcon; + + private static int state = 0; + + public static MageTray getInstance() { + return instance; + } + + public void install() { + if (!SystemTray.isSupported()) { + log.warn("SystemTray is not supported"); + return; + } + + try { + mainImage = ImageManagerImpl.getInstance().getAppSmallImage(); + flashedImage = ImageManagerImpl.getInstance().getAppFlashedImage(); + trayIcon = new TrayIcon(mainImage); + trayIcon.setImageAutoSize(true); + + trayIcon.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + stopBlink(); + MageFrame frame = MageFrame.getInstance(); + frame.setVisible(true); + frame.setState(Frame.NORMAL); + } + }); + + final SystemTray tray = SystemTray.getSystemTray(); + + final PopupMenu popup = new PopupMenu(); + + MenuItem imagesItem = new MenuItem("Download images"); + MenuItem iconsItem = new MenuItem("Download icons"); + MenuItem stopBlinkItem = new MenuItem("Stop blinking"); + MenuItem preferencesItem = new MenuItem("Preferences..."); + MenuItem aboutItem = new MenuItem("About Mage"); + MenuItem exitItem = new MenuItem("Exit"); + + imagesItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MageFrame.getInstance().btnImagesActionPerformed(null); + } + }); + + iconsItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MageFrame.getInstance().btnSymbolsActionPerformed(null); + } + }); + + stopBlinkItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + stopBlink(); + } + }); + + preferencesItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MageFrame.getInstance().btnPreferencesActionPerformed(null); + } + }); + + aboutItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MageFrame.getInstance().btnAboutActionPerformed(null); + } + }); + + exitItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MageFrame.getInstance().exitApp(); + } + }); + + popup.add(imagesItem); + popup.add(iconsItem); + popup.add(stopBlinkItem); + popup.add(preferencesItem); + popup.addSeparator(); + popup.add(aboutItem); + popup.addSeparator(); + popup.add(exitItem); + + trayIcon.setPopupMenu(popup); + + try { + tray.add(trayIcon); + } catch (AWTException e) { + log.error("TrayIcon could not be added: ", e); + return; + } + + } catch (Exception e) { + log.error(e); + } + } + + public synchronized void blink() { + if (state == 0) { + synchronized (MageTray.class) { + if (state == 0) { + state = 1; + new Thread(new Runnable() { + @Override + public void run() { + try { + int i = 0; + while (state != 3) { + trayIcon.setImage(i == 0 ? mainImage : flashedImage); + Thread.sleep(600); + i = i == 0 ? 1 : 0; + } + trayIcon.setImage(mainImage); + state = 0; + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + }).start(); + } + } + } + } + + public void stopBlink() { + if (state == 1) { + state = 3; + } + } +} diff --git a/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java b/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java index 5ff9d6d0c1..bbfc8a6cdb 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java @@ -107,6 +107,10 @@ public class MageDialog extends javax.swing.JInternalFrame { Object source = event.getSource(); boolean dispatch = true; + if (event.getSource() != null && event.getSource() instanceof TrayIcon) { + return; + } + if (event instanceof MouseEvent && event.getSource() instanceof Component) { MouseEvent e = (MouseEvent) event; MouseEvent m = SwingUtilities.convertMouseEvent((Component) e.getSource(), e, this); diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java index bdd2a156c0..5b9ea99c66 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java @@ -34,20 +34,22 @@ package mage.client.dialog; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import javax.swing.SwingWorker; -import javax.swing.table.AbstractTableModel; -import mage.client.*; +import mage.client.MageFrame; import mage.client.chat.ChatPanel; import mage.client.components.MageComponents; +import mage.client.components.tray.MageTray; import mage.remote.Session; import mage.view.SeatView; import mage.view.TableView; import org.apache.log4j.Logger; +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; + /** * * @author BetaSteward_at_googlemail.com @@ -359,6 +361,7 @@ class UpdateSeatsTask extends SwingWorker { private UUID roomId; private UUID tableId; private TableWaitingDialog dialog; + private int count = 0; private final static Logger logger = Logger.getLogger(TableWaitingDialog.class); @@ -380,9 +383,34 @@ class UpdateSeatsTask extends SwingWorker { @Override protected void process(List view) { - dialog.update(view.get(0)); + TableView tableView = view.get(0); + if (count == 0) { + count = getPlayersCount(tableView); + } else { + int current = getPlayersCount(tableView); + if (current != count) { + count = current; + if (count > 0) { + MageTray.getInstance().blink(); + } + } + } + dialog.update(tableView); } + private int getPlayersCount(TableView tableView) { + int count = 0; + if (tableView != null) { + for (SeatView seatView: tableView.getSeats()) { + if (seatView.getPlayerId() != null && seatView.getPlayerType().equals("Human")) { + count++; + } + } + } + return count; + } + + @Override protected void done() { try { diff --git a/Mage.Client/src/main/resources/icon-mage-flashed.png b/Mage.Client/src/main/resources/icon-mage-flashed.png new file mode 100644 index 0000000000000000000000000000000000000000..588dd79d8efa9c5a60411d87588e8f5b0515d884 GIT binary patch literal 3895 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