From c328c71ef9715f8d2745a7955a3e44d62fa19af4 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sun, 15 Aug 2021 10:47:19 +0400 Subject: [PATCH] GUI: chats code upgraded to use new popup hint code; --- .../mage/client/cards/VirtualCardInfo.java | 14 ++- .../java/mage/client/chat/ChatPanelBasic.java | 5 + .../mage/client/components/ColorPane.java | 92 +++++++++---------- .../main/java/mage/client/game/GamePanel.java | 6 ++ .../plugins/adapters/MageActionCallback.java | 15 ++- .../mage/client/table/PlayersChatPanel.java | 6 ++ .../java/mage/cards/action/TransferData.java | 11 ++- 7 files changed, 96 insertions(+), 53 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/cards/VirtualCardInfo.java b/Mage.Client/src/main/java/mage/client/cards/VirtualCardInfo.java index a01b2dd7e9..9013339590 100644 --- a/Mage.Client/src/main/java/mage/client/cards/VirtualCardInfo.java +++ b/Mage.Client/src/main/java/mage/client/cards/VirtualCardInfo.java @@ -18,9 +18,17 @@ import java.util.UUID; * GUI: virtual card component for popup hint (move mouse over card to show a hint) *

* Use case: you don't have a real card but want to show a popup card hint. + *

* Howto use: * - call "init" on new card; - * - call "onMouseXXX" on start, update and close + * - call "onMouseEntered" to prepare; + * - call "onMouseMoved" to draw; + * - call "onMouseExited" to hide; + *

+ * Hints: + * - for game GUI: you must init with gameId (otherwise you can't see it) + * - for non-game GUI: no needs in gameId or bigCard (bigCard is a panel with card image) + * - if you want to show card immediately then use init + onMouseEntered + onMouseMoved * * @author JayDi85 */ @@ -78,6 +86,10 @@ public class VirtualCardInfo { data.setGameId(gameId); } + public void setTooltipDelay(int tooltipDelay) { + data.setTooltipDelay(tooltipDelay); + } + public boolean prepared() { return this.cardView != null && this.cardComponent != null diff --git a/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java b/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java index 4848736fd6..b0c607bc5e 100644 --- a/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java +++ b/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java @@ -2,6 +2,7 @@ package mage.client.chat; import mage.client.MageFrame; import mage.client.SessionHandler; +import mage.client.cards.BigCard; import mage.client.dialog.PreferencesDialog; import mage.client.util.GUISizeHelper; import mage.view.ChatMessage.MessageColor; @@ -102,10 +103,14 @@ public class ChatPanelBasic extends javax.swing.JPanel { jScrollPaneTxt.getViewport().setBackground(new Color(0, 0, 0, CHAT_ALPHA)); jScrollPaneTxt.setViewportBorder(null); } + } public void cleanUp() { + } + public void setGameData(UUID gameId, BigCard bigCard) { + txtConversation.setGameData(gameId, bigCard); } public void changeGUISize(Font font) { diff --git a/Mage.Client/src/main/java/mage/client/components/ColorPane.java b/Mage.Client/src/main/java/mage/client/components/ColorPane.java index b10f2f6d26..3815b99d2d 100644 --- a/Mage.Client/src/main/java/mage/client/components/ColorPane.java +++ b/Mage.Client/src/main/java/mage/client/components/ColorPane.java @@ -2,10 +2,9 @@ package mage.client.components; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; -import mage.client.MageFrame; +import mage.client.cards.BigCard; +import mage.client.cards.VirtualCardInfo; import mage.client.dialog.PreferencesDialog; -import mage.client.util.gui.GuiDisplayUtil; -import mage.components.CardInfoPane; import mage.game.command.Plane; import mage.util.CardUtil; import mage.utils.ThreadUtils; @@ -23,19 +22,26 @@ import java.awt.event.MouseEvent; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; +import java.util.UUID; /** - * Enhanced {@link JTextPane} with text highlighting support. + * GUI: chats with html and hints popup support for objects * - * @author nantuko + * @author nantuko, JayDi85 */ public class ColorPane extends JEditorPane { final HTMLEditorKit kit = new HTMLEditorKit(); final HTMLDocument doc = new HTMLDocument(); - private int tooltipDelay; - private int tooltipCounter; + + private static final int CHAT_TOOLTIP_DELAY_MS = 50; // cards popup from chat must be fast all time + + // cards popup info private boolean hyperlinkEnabled = false; + VirtualCardInfo cardInfo = new VirtualCardInfo(); + UUID gameId = null; + BigCard bigCard = null; + public ColorPane() { this.setEditorKit(kit); @@ -44,8 +50,8 @@ public class ColorPane extends JEditorPane { private void addHyperlinkHandlers() { addHyperlinkListener(e -> ThreadUtils.threadPool2.submit(() -> { - tooltipDelay = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300); - if (tooltipDelay == 0) { + if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300) == 0) { + // if disabled return; } @@ -77,60 +83,50 @@ public class ColorPane extends JEditorPane { if (!alternativeName.isEmpty()) { cardName = alternativeName; } - try { - final Component container = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER); - if (e.getEventType() == EventType.EXITED) { - setPopupVisibility(container, false); - } - if (e.getEventType() == EventType.ENTERED) { - CardInfoPane cardInfoPane = (CardInfoPane) MageFrame.getUI().getComponent(MageComponents.CARD_INFO_PANE); - // card - CardInfo card = CardRepository.instance.findCard(cardName); + if (e.getEventType() == EventType.ENTERED) { + CardView cardView = null; + + // card + CardInfo card = CardRepository.instance.findCards(cardName).stream().findFirst().orElse(null); + if (card != null) { + cardView = new CardView(card.getMockCard()); + } + + // plane + if (cardView == null) { Plane plane = Plane.createPlaneByFullName(cardName); - if (card != null) { - cardInfoPane.setCard(new CardView(card.getMockCard()), container); - setPopupVisibility(container, true); - } else if (plane != null) { - cardInfoPane.setCard(new CardView(new PlaneView(plane)), container); - setPopupVisibility(container, true); + if (plane != null) { + cardView = new CardView(new PlaneView(plane)); } } - } catch (InterruptedException e1) { - e1.printStackTrace(); + + // TODO: add other objects like dungeon, emblem, commander + + if (cardView != null) { + cardInfo.init(cardView, this.bigCard, this.gameId); + cardInfo.setTooltipDelay(CHAT_TOOLTIP_DELAY_MS); + cardInfo.onMouseEntered(MouseInfo.getPointerInfo().getLocation()); + cardInfo.onMouseMoved(MouseInfo.getPointerInfo().getLocation()); + } } + if (e.getEventType() == EventType.EXITED) { + cardInfo.onMouseExited(); + } })); addMouseListener(new MouseAdapter() { @Override public void mouseExited(MouseEvent e) { - tooltipCounter = 1; // will decrement and become effectively zero on leaving the pane - try { - setPopupVisibility(MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER), false); - } catch (InterruptedException e1) { - e1.printStackTrace(); - } + cardInfo.onMouseExited(); } }); } - private void setPopupVisibility(final Component container, final boolean show) throws InterruptedException { - final Component c = MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE); - SwingUtilities.invokeLater(() -> { - tooltipCounter += show ? 1 : -1; - if (tooltipCounter < 0) { - tooltipCounter = 0; - } - if (tooltipCounter > 0) { - Point location = new Point(this.getLocationOnScreen().x - container.getWidth(), MouseInfo.getPointerInfo().getLocation().y); - Component parentComponent = MageFrame.getInstance(); - location = GuiDisplayUtil.keepComponentInsideParent(location, parentComponent.getLocationOnScreen(), container, parentComponent); - container.setLocation(location); - } - container.setVisible(tooltipCounter > 0); - c.repaint(); - }); + public void setGameData(UUID gameId, BigCard bigCard) { + this.gameId = gameId; + this.bigCard = bigCard; } /** diff --git a/Mage.Client/src/main/java/mage/client/game/GamePanel.java b/Mage.Client/src/main/java/mage/client/game/GamePanel.java index d5e1165067..50d60dfd7a 100644 --- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java +++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java @@ -465,6 +465,10 @@ public final class GamePanel extends javax.swing.JPanel { this.btnCancelSkip.setVisible(true); this.btnToggleMacro.setVisible(true); + // cards popup info in chats + this.gameChatPanel.setGameData(gameId, bigCard); + this.userChatPanel.setGameData(gameId, bigCard); + this.btnSkipToNextTurn.setVisible(true); this.btnSkipToEndTurn.setVisible(true); this.btnSkipToNextMain.setVisible(true); @@ -1915,6 +1919,8 @@ public final class GamePanel extends javax.swing.JPanel { bigCard.setBorder(new LineBorder(Color.black, 1, true)); + // CHATS and HINTS support + // HOTKEYS int c = JComponent.WHEN_IN_FOCUSED_WINDOW; diff --git a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java index 685ab57f1c..edabb05841 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java +++ b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java @@ -43,12 +43,14 @@ import java.util.concurrent.TimeUnit; /** * Class that handles the callbacks from the card panels to mage to display big * card images from the cards the mouse hovers on. Also handles tooltip text - * window. + * window (from non-card calls, example: chats) *

* Only ONE action callback possible for the app *

* If you want to process card events in your component then use CardEventProducer, see example with mouseClicked here * + * If you want virtual popup hint (without real card) then use VirtualCardInfo + * * @author Nantuko, noxx, JayDi85 */ public class MageActionCallback implements ActionCallback { @@ -140,8 +142,15 @@ public class MageActionCallback implements ActionCallback { private void startCardHintPopup(final TransferData data, final Component parentComponent, final Point parentPoint) { MageCard cardPanel = data.getComponent().getTopPanelRef(); - tooltipDelay = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300); + if (data.getTooltipDelay() > 0) { + // custom tooltip + tooltipDelay = data.getTooltipDelay(); + } else { + // from preferences + tooltipDelay = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300); + } if (tooltipDelay == 0) { + // disabled return; } @@ -449,7 +458,7 @@ public class MageActionCallback implements ActionCallback { // Prevent to show tooltips from panes not in front MagePane topPane = MageFrame.getTopMost(null); if (topPane instanceof GamePane) { - if (!((GamePane) topPane).getGameId().equals(data.getGameId())) { + if (data.getGameId() != null && !((GamePane) topPane).getGameId().equals(data.getGameId())) { return; } } diff --git a/Mage.Client/src/main/java/mage/client/table/PlayersChatPanel.java b/Mage.Client/src/main/java/mage/client/table/PlayersChatPanel.java index 032ef1ea65..4ca7a4f412 100644 --- a/Mage.Client/src/main/java/mage/client/table/PlayersChatPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/PlayersChatPanel.java @@ -1,5 +1,6 @@ package mage.client.table; +import mage.client.cards.BigCard; import mage.client.chat.ChatPanelBasic; import mage.client.util.GUISizeHelper; import mage.client.util.MageTableRowSorter; @@ -18,6 +19,7 @@ import java.awt.*; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.UUID; import static mage.client.chat.ChatPanelBasic.CHAT_ALPHA; import static mage.client.dialog.PreferencesDialog.KEY_USERS_COLUMNS_ORDER; @@ -103,6 +105,10 @@ public class PlayersChatPanel extends javax.swing.JPanel { jScrollPaneTalk.cleanUp(); } + public void setGameData(UUID gameId, BigCard bigCard) { + colorPaneSystem.setGameData(gameId, bigCard); + } + public void changeGUISize() { setGUISize(); } diff --git a/Mage.Common/src/main/java/mage/cards/action/TransferData.java b/Mage.Common/src/main/java/mage/cards/action/TransferData.java index 9f273f182b..b0baf704ec 100644 --- a/Mage.Common/src/main/java/mage/cards/action/TransferData.java +++ b/Mage.Common/src/main/java/mage/cards/action/TransferData.java @@ -15,11 +15,12 @@ public class TransferData { private MageCard component; // real card panel (it may lie under multiple layer panels, so use getTopPanelRef for top) private TextPopup popupText; - private Point locationOnScreen; // must contains REAL card location (e.g. without outer/draw spaces), so use getCardLocationOnScreen to update it + private Point locationOnScreen; // must contain REAL card location (e.g. without outer/draw spaces), so use getCardLocationOnScreen to update it private int popupOffsetX; private int popupOffsetY; private UUID gameId; private CardView card; + private int tooltipDelay; // custom delay, set non-zero to overwrite preferences settings /** * If you use it with cards then call top layer panel like data.getComponent().getTopPanelRef() @@ -81,4 +82,12 @@ public class TransferData { public void setCard(CardView card) { this.card = card; } + + public int getTooltipDelay() { + return tooltipDelay; + } + + public void setTooltipDelay(int tooltipDelay) { + this.tooltipDelay = tooltipDelay; + } }