GUI: chats code upgraded to use new popup hint code;

This commit is contained in:
Oleg Agafonov 2021-08-15 10:47:19 +04:00
parent 5725e15771
commit c328c71ef9
7 changed files with 96 additions and 53 deletions

View file

@ -18,9 +18,17 @@ import java.util.UUID;
* GUI: virtual card component for popup hint (move mouse over card to show a hint) * GUI: virtual card component for popup hint (move mouse over card to show a hint)
* <p> * <p>
* Use case: you don't have a real card but want to show a popup card hint. * Use case: you don't have a real card but want to show a popup card hint.
* <p>
* Howto use: * Howto use:
* - call "init" on new card; * - call "init" on new card;
* - call "onMouseXXX" on start, update and close * - call "onMouseEntered" to prepare;
* - call "onMouseMoved" to draw;
* - call "onMouseExited" to hide;
* <p>
* 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 * @author JayDi85
*/ */
@ -78,6 +86,10 @@ public class VirtualCardInfo {
data.setGameId(gameId); data.setGameId(gameId);
} }
public void setTooltipDelay(int tooltipDelay) {
data.setTooltipDelay(tooltipDelay);
}
public boolean prepared() { public boolean prepared() {
return this.cardView != null return this.cardView != null
&& this.cardComponent != null && this.cardComponent != null

View file

@ -2,6 +2,7 @@ package mage.client.chat;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.SessionHandler; import mage.client.SessionHandler;
import mage.client.cards.BigCard;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import mage.client.util.GUISizeHelper; import mage.client.util.GUISizeHelper;
import mage.view.ChatMessage.MessageColor; 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.getViewport().setBackground(new Color(0, 0, 0, CHAT_ALPHA));
jScrollPaneTxt.setViewportBorder(null); jScrollPaneTxt.setViewportBorder(null);
} }
} }
public void cleanUp() { public void cleanUp() {
}
public void setGameData(UUID gameId, BigCard bigCard) {
txtConversation.setGameData(gameId, bigCard);
} }
public void changeGUISize(Font font) { public void changeGUISize(Font font) {

View file

@ -2,10 +2,9 @@ package mage.client.components;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository; 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.dialog.PreferencesDialog;
import mage.client.util.gui.GuiDisplayUtil;
import mage.components.CardInfoPane;
import mage.game.command.Plane; import mage.game.command.Plane;
import mage.util.CardUtil; import mage.util.CardUtil;
import mage.utils.ThreadUtils; import mage.utils.ThreadUtils;
@ -23,19 +22,26 @@ import java.awt.event.MouseEvent;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; 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 { public class ColorPane extends JEditorPane {
final HTMLEditorKit kit = new HTMLEditorKit(); final HTMLEditorKit kit = new HTMLEditorKit();
final HTMLDocument doc = new HTMLDocument(); 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; private boolean hyperlinkEnabled = false;
VirtualCardInfo cardInfo = new VirtualCardInfo();
UUID gameId = null;
BigCard bigCard = null;
public ColorPane() { public ColorPane() {
this.setEditorKit(kit); this.setEditorKit(kit);
@ -44,8 +50,8 @@ public class ColorPane extends JEditorPane {
private void addHyperlinkHandlers() { private void addHyperlinkHandlers() {
addHyperlinkListener(e -> ThreadUtils.threadPool2.submit(() -> { addHyperlinkListener(e -> ThreadUtils.threadPool2.submit(() -> {
tooltipDelay = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300); if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300) == 0) {
if (tooltipDelay == 0) { // if disabled
return; return;
} }
@ -77,60 +83,50 @@ public class ColorPane extends JEditorPane {
if (!alternativeName.isEmpty()) { if (!alternativeName.isEmpty()) {
cardName = alternativeName; 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) { if (e.getEventType() == EventType.ENTERED) {
CardInfoPane cardInfoPane = (CardInfoPane) MageFrame.getUI().getComponent(MageComponents.CARD_INFO_PANE); CardView cardView = null;
// card // card
CardInfo card = CardRepository.instance.findCard(cardName); CardInfo card = CardRepository.instance.findCards(cardName).stream().findFirst().orElse(null);
Plane plane = Plane.createPlaneByFullName(cardName);
if (card != null) { if (card != null) {
cardInfoPane.setCard(new CardView(card.getMockCard()), container); cardView = new CardView(card.getMockCard());
setPopupVisibility(container, true);
} else if (plane != null) {
cardInfoPane.setCard(new CardView(new PlaneView(plane)), container);
setPopupVisibility(container, true);
}
}
} catch (InterruptedException e1) {
e1.printStackTrace();
} }
// plane
if (cardView == null) {
Plane plane = Plane.createPlaneByFullName(cardName);
if (plane != null) {
cardView = new CardView(new PlaneView(plane));
}
}
// 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() { addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseExited(MouseEvent e) { public void mouseExited(MouseEvent e) {
tooltipCounter = 1; // will decrement and become effectively zero on leaving the pane cardInfo.onMouseExited();
try {
setPopupVisibility(MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER), false);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} }
}); });
} }
private void setPopupVisibility(final Component container, final boolean show) throws InterruptedException { public void setGameData(UUID gameId, BigCard bigCard) {
final Component c = MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE); this.gameId = gameId;
SwingUtilities.invokeLater(() -> { this.bigCard = bigCard;
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();
});
} }
/** /**

View file

@ -465,6 +465,10 @@ public final class GamePanel extends javax.swing.JPanel {
this.btnCancelSkip.setVisible(true); this.btnCancelSkip.setVisible(true);
this.btnToggleMacro.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.btnSkipToNextTurn.setVisible(true);
this.btnSkipToEndTurn.setVisible(true); this.btnSkipToEndTurn.setVisible(true);
this.btnSkipToNextMain.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)); bigCard.setBorder(new LineBorder(Color.black, 1, true));
// CHATS and HINTS support
// HOTKEYS // HOTKEYS
int c = JComponent.WHEN_IN_FOCUSED_WINDOW; int c = JComponent.WHEN_IN_FOCUSED_WINDOW;

View file

@ -43,12 +43,14 @@ import java.util.concurrent.TimeUnit;
/** /**
* Class that handles the callbacks from the card panels to mage to display big * 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 * card images from the cards the mouse hovers on. Also handles tooltip text
* window. * window (from non-card calls, example: chats)
* <p> * <p>
* Only ONE action callback possible for the app * Only ONE action callback possible for the app
* <p> * <p>
* If you want to process card events in your component then use CardEventProducer, see example with mouseClicked here * 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 * @author Nantuko, noxx, JayDi85
*/ */
public class MageActionCallback implements ActionCallback { 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) { private void startCardHintPopup(final TransferData data, final Component parentComponent, final Point parentPoint) {
MageCard cardPanel = data.getComponent().getTopPanelRef(); MageCard cardPanel = data.getComponent().getTopPanelRef();
if (data.getTooltipDelay() > 0) {
// custom tooltip
tooltipDelay = data.getTooltipDelay();
} else {
// from preferences
tooltipDelay = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300); tooltipDelay = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300);
}
if (tooltipDelay == 0) { if (tooltipDelay == 0) {
// disabled
return; return;
} }
@ -449,7 +458,7 @@ public class MageActionCallback implements ActionCallback {
// Prevent to show tooltips from panes not in front // Prevent to show tooltips from panes not in front
MagePane topPane = MageFrame.getTopMost(null); MagePane topPane = MageFrame.getTopMost(null);
if (topPane instanceof GamePane) { if (topPane instanceof GamePane) {
if (!((GamePane) topPane).getGameId().equals(data.getGameId())) { if (data.getGameId() != null && !((GamePane) topPane).getGameId().equals(data.getGameId())) {
return; return;
} }
} }

View file

@ -1,5 +1,6 @@
package mage.client.table; package mage.client.table;
import mage.client.cards.BigCard;
import mage.client.chat.ChatPanelBasic; import mage.client.chat.ChatPanelBasic;
import mage.client.util.GUISizeHelper; import mage.client.util.GUISizeHelper;
import mage.client.util.MageTableRowSorter; import mage.client.util.MageTableRowSorter;
@ -18,6 +19,7 @@ import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.UUID;
import static mage.client.chat.ChatPanelBasic.CHAT_ALPHA; import static mage.client.chat.ChatPanelBasic.CHAT_ALPHA;
import static mage.client.dialog.PreferencesDialog.KEY_USERS_COLUMNS_ORDER; import static mage.client.dialog.PreferencesDialog.KEY_USERS_COLUMNS_ORDER;
@ -103,6 +105,10 @@ public class PlayersChatPanel extends javax.swing.JPanel {
jScrollPaneTalk.cleanUp(); jScrollPaneTalk.cleanUp();
} }
public void setGameData(UUID gameId, BigCard bigCard) {
colorPaneSystem.setGameData(gameId, bigCard);
}
public void changeGUISize() { public void changeGUISize() {
setGUISize(); setGUISize();
} }

View file

@ -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 MageCard component; // real card panel (it may lie under multiple layer panels, so use getTopPanelRef for top)
private TextPopup popupText; 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 popupOffsetX;
private int popupOffsetY; private int popupOffsetY;
private UUID gameId; private UUID gameId;
private CardView card; 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() * 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) { public void setCard(CardView card) {
this.card = card; this.card = card;
} }
public int getTooltipDelay() {
return tooltipDelay;
}
public void setTooltipDelay(int tooltipDelay) {
this.tooltipDelay = tooltipDelay;
}
} }