diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 32cab3a0391..4718c150b29 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -43,6 +43,7 @@ import mage.interfaces.callback.CallbackClient; import mage.interfaces.callback.ClientCallback; import mage.remote.Connection; import mage.remote.Connection.ProxyType; +import mage.util.DebugUtil; import mage.utils.MageVersion; import mage.view.GameEndView; import mage.view.UserRequestMessage; @@ -417,6 +418,9 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { popupContainer.setLayout(null); popupContainer.add(cardInfoPane); popupContainer.setVisible(false); + if (DebugUtil.GUI_POPUP_CONTAINER_DRAW_DEBUG_BORDER) { + popupContainer.setBorder(BorderFactory.createLineBorder(Color.red)); + } desktopPane.add(popupContainer, JLayeredPane.POPUP_LAYER); UI.addComponent(MageComponents.POPUP_CONTAINER, popupContainer); 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 270371b1459..b35e9429f36 100644 --- a/Mage.Client/src/main/java/mage/client/cards/VirtualCardInfo.java +++ b/Mage.Client/src/main/java/mage/client/cards/VirtualCardInfo.java @@ -29,6 +29,10 @@ import java.util.UUID; * - 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 + *
+ * Auto-location modes: + * - default: popup container will be put inside parent container + * - near mouse: popup container will be put near mouse position (example: popup over chat messages) * * @author JayDi85 */ @@ -90,6 +94,10 @@ public class VirtualCardInfo { data.setTooltipDelay(tooltipDelay); } + public void setPopupAutoLocationMode(TransferData.PopupAutoLocationMode mode) { + data.setPopupAutoLocationMode(mode); + } + public CardView getCardView() { return this.cardView; } @@ -125,10 +133,6 @@ public class VirtualCardInfo { this.actionCallback.mouseEntered(null, this.data); } - public void onMouseMoved() { - onMouseMoved(null); - } - public void onMouseMoved(Point newLocation) { if (!prepared()) { return; @@ -145,6 +149,7 @@ public class VirtualCardInfo { if (!prepared()) { return; } + this.actionCallback.mouseExited(null, this.data); } } 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 25d11cb1aea..968c55bc66e 100644 --- a/Mage.Client/src/main/java/mage/client/components/ColorPane.java +++ b/Mage.Client/src/main/java/mage/client/components/ColorPane.java @@ -1,5 +1,6 @@ package mage.client.components; +import mage.cards.action.TransferData; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; import mage.client.cards.BigCard; @@ -109,6 +110,7 @@ public class ColorPane extends JEditorPane { if (cardView != null) { cardInfo.init(cardView, this.bigCard, this.gameId); cardInfo.setTooltipDelay(CHAT_TOOLTIP_DELAY_MS); + cardInfo.setPopupAutoLocationMode(TransferData.PopupAutoLocationMode.PUT_NEAR_MOUSE_POSITION); cardInfo.onMouseEntered(MouseInfo.getPointerInfo().getLocation()); cardInfo.onMouseMoved(MouseInfo.getPointerInfo().getLocation()); } diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java index a406252a676..7edc9f157bc 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java @@ -7,6 +7,7 @@ import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; +import mage.cards.action.TransferData; import mage.choices.Choice; import mage.choices.ChoiceHintType; import mage.client.MageFrame; @@ -238,6 +239,7 @@ public class PickChoiceDialog extends MageDialog { CardView cardView = new CardView(new DungeonView(Dungeon.createDungeon(cardName))); cardInfo.init(cardView, this.bigCard, this.gameId); } + cardInfo.setPopupAutoLocationMode(TransferData.PopupAutoLocationMode.PUT_NEAR_MOUSE_POSITION); cardInfo.onMouseEntered(MouseInfo.getPointerInfo().getLocation()); } else { 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 766c1a9d38f..8a42357ab65 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 @@ -21,6 +21,7 @@ import mage.client.util.gui.GuiDisplayUtil; import mage.components.CardInfoPane; import mage.constants.EnlargeMode; import mage.constants.Zone; +import mage.util.DebugUtil; import mage.utils.ThreadUtils; import mage.view.CardView; import mage.view.PermanentView; @@ -48,7 +49,7 @@ import java.util.concurrent.TimeUnit; * 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 @@ -167,13 +168,17 @@ public class MageActionCallback implements ActionCallback { if (data.getLocationOnScreen() == null) { data.setLocationOnScreen(cardPanel.getCardLocationOnScreen().getCardPoint()); } + + int newLocationX = (int) data.getLocationOnScreen().getX() + data.getPopupOffsetX(); + int newLocationY = (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() + 40; + PopupFactory factory = PopupFactory.getSharedInstance(); data.getPopupText().updateText(); - tooltipPopup = factory.getPopup(cardPanel, data.getPopupText(), (int) data.getLocationOnScreen().getX() + data.getPopupOffsetX(), (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() + 40); + tooltipPopup = factory.getPopup(cardPanel, data.getPopupText(), newLocationX, newLocationY); tooltipPopup.show(); - // hack to get popup to resize to fit text + // hack to get popup to resize to fit text TODO: wtf?! Can be removed? tooltipPopup.hide(); - tooltipPopup = factory.getPopup(cardPanel, data.getPopupText(), (int) data.getLocationOnScreen().getX() + data.getPopupOffsetX(), (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() + 40); + tooltipPopup = factory.getPopup(cardPanel, data.getPopupText(), newLocationX, newLocationY); tooltipPopup.show(); } else { showCardHintPopup(data, parentComponent, parentPoint); @@ -218,9 +223,11 @@ public class MageActionCallback implements ActionCallback { data.setLocationOnScreen(cardPanel.getCardLocationOnScreen().getCardPoint()); } - Point location = new Point((int) data.getLocationOnScreen().getX() + data.getPopupOffsetX() - 40, (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() - 40); - location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, infoPane, parentComponent); - location.translate(-parentPoint.x, -parentPoint.y); + if (DebugUtil.GUI_POPUP_CONTAINER_DRAW_DEBUG_BORDER) { + ((JComponent) infoPane).setBorder(BorderFactory.createLineBorder(Color.green)); + } + + Point location = preparePopupContainerLocation(popupContainer, infoPane, data, parentPoint, parentComponent); popupContainer.setLocation(location); popupContainer.setVisible(true); c.repaint(); @@ -672,10 +679,12 @@ public class MageActionCallback implements ActionCallback { Component parentComponent = SwingUtilities.getRoot(cardPanel); if (cardPreviewPane != null && parentComponent != null) { Point parentPoint = parentComponent.getLocationOnScreen(); + if (DebugUtil.GUI_POPUP_CONTAINER_DRAW_DEBUG_BORDER) { + ((JComponent) cardPreviewPane).setBorder(BorderFactory.createLineBorder(Color.green)); + } data.setLocationOnScreen(cardPanel.getCardLocationOnScreen().getCardPoint()); - Point location = new Point((int) data.getLocationOnScreen().getX() + data.getPopupOffsetX() - 40, (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() - 40); - location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, cardPreviewPane, parentComponent); - location.translate(-parentPoint.x, -parentPoint.y); + + Point location = preparePopupContainerLocation(popupContainer, cardPreviewPane, data, parentPoint, parentComponent); popupContainer.setLocation(location); popupContainer.setVisible(true); @@ -717,6 +726,37 @@ public class MageActionCallback implements ActionCallback { }); } + private Point preparePopupContainerLocation(Component popupContainer, Component popupComponent, TransferData data, Point parentPoint, Component parentComponent) { + Point location; + switch (data.getPopupAutoLocationMode()) { + + case PUT_INSIDE_PARENT: { + location = new Point((int) data.getLocationOnScreen().getX() + data.getPopupOffsetX() - 40, (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() - 40); + location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, popupComponent, parentComponent); + location.translate(-parentPoint.x, -parentPoint.y); + break; + } + + case PUT_NEAR_MOUSE_POSITION: { + location = MouseInfo.getPointerInfo().getLocation(); + boolean hasRightSpace = location.x + popupContainer.getWidth() < parentComponent.getX() + parentComponent.getWidth(); + boolean hasBottomSpace = location.y + popupContainer.getHeight() < parentComponent.getY() + parentComponent.getHeight(); + if (!hasRightSpace) { + location.setLocation(location.x - popupContainer.getWidth(), location.y); + } + if (!hasBottomSpace) { + location.setLocation(location.x, location.y - popupContainer.getHeight()); + } + break; + } + + default: + throw new IllegalArgumentException("Unsupport auto-location " + data.getPopupAutoLocationMode()); + } + location.translate(-parentPoint.x, -parentPoint.y); + return location; + } + private void displayCardInfo(CardView card, Image image, BigCard bigCard) { if (image instanceof BufferedImage) { // XXX: scaled to fit width diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/info/CardInfoPaneImpl.java b/Mage.Client/src/main/java/org/mage/plugins/card/info/CardInfoPaneImpl.java index 43b1273b910..1817e11f9f3 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/info/CardInfoPaneImpl.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/info/CardInfoPaneImpl.java @@ -11,7 +11,7 @@ import mage.view.CardView; import org.mage.card.arcane.UI; /** - * Card info pane for displaying card rules. Supports drawing mana symbols. + * GUI: card info pane for displaying card rules (example: text mode for popup card). Supports drawing mana symbols. * * @author nantuko */ 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 b0baf704ec9..d1f9c42f3e3 100644 --- a/Mage.Common/src/main/java/mage/cards/action/TransferData.java +++ b/Mage.Common/src/main/java/mage/cards/action/TransferData.java @@ -18,10 +18,16 @@ public class TransferData { 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 PopupAutoLocationMode popupAutoLocationMode = PopupAutoLocationMode.PUT_INSIDE_PARENT; private UUID gameId; private CardView card; private int tooltipDelay; // custom delay, set non-zero to overwrite preferences settings + public enum PopupAutoLocationMode { + PUT_INSIDE_PARENT, + PUT_NEAR_MOUSE_POSITION + } + /** * If you use it with cards then call top layer panel like data.getComponent().getTopPanelRef() * @@ -90,4 +96,12 @@ public class TransferData { public void setTooltipDelay(int tooltipDelay) { this.tooltipDelay = tooltipDelay; } + + public void setPopupAutoLocationMode(PopupAutoLocationMode mode) { + this.popupAutoLocationMode = mode; + } + + public PopupAutoLocationMode getPopupAutoLocationMode() { + return this.popupAutoLocationMode; + } } diff --git a/Mage/src/main/java/mage/util/DebugUtil.java b/Mage/src/main/java/mage/util/DebugUtil.java index 28017431d34..e8242f0efe9 100644 --- a/Mage/src/main/java/mage/util/DebugUtil.java +++ b/Mage/src/main/java/mage/util/DebugUtil.java @@ -22,6 +22,9 @@ public class DebugUtil { public static boolean GUI_RENDER_IMAGE_DRAW_IMAGE_BORDER = false; public static boolean GUI_RENDER_CENTERED_TEXT_DRAW_DEBUG_LINES = false; + // popup container (example: popup with card info) + public static boolean GUI_POPUP_CONTAINER_DRAW_DEBUG_BORDER = false; + // deck editor public static boolean GUI_DECK_EDITOR_DRAW_DRAGGING_PANE_BORDER = false; public static boolean GUI_DECK_EDITOR_DRAW_COUNT_LABEL_BORDER = false;