diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java index 0e6f3e68ab4..e987c1f908a 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java @@ -517,7 +517,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen @Override public final void mouseLeftClicked(final CardPanel panel, final MouseEvent evt) { - selectCard(panel, evt); + selectCard(panel, new MouseTriggerEvent(evt), evt.isShiftDown()); //select entire stack if shift key down if ((panel.getTappedAngle() != 0) && (panel.getTappedAngle() != CardPanel.TAPPED_ANGLE)) { return; } @@ -526,19 +526,14 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen @Override public final void mouseRightClicked(final CardPanel panel, final MouseEvent evt) { - selectCard(panel, evt); + selectCard(panel, new MouseTriggerEvent(evt), false); super.mouseRightClicked(panel, evt); } - private void selectCard(final CardPanel panel, final MouseEvent evt) { - //on Shift+left-click, select all other cards in stack if any - selectCard(panel, new MouseTriggerEvent(evt), evt.getButton() == 1 && evt.isShiftDown()); - } - - private boolean selectCard(final CardPanel panel, final MouseTriggerEvent triggerEvent, final boolean selectOtherCardsInStack) { + private boolean selectCard(final CardPanel panel, final MouseTriggerEvent triggerEvent, final boolean selectEntireStack) { List otherCardViewsToSelect = null; List stack = panel.getStack(); - if (selectOtherCardsInStack) { + if (selectEntireStack) { if (stack != null) { for (CardPanel p : stack) { if (p != panel && p.getCard() != null && p.getStack() == stack) { @@ -557,7 +552,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen if (stack != null) { for (int i = stack.indexOf(panel) + 1; i < stack.size(); i++) { //looping forward since panels stored in reverse order CardPanel p = stack.get(i); - if (p.getStack() == stack && selectCard(stack.get(i), triggerEvent, selectOtherCardsInStack)) { + if (p.getStack() == stack && selectCard(stack.get(i), triggerEvent, selectEntireStack)) { return true; } } @@ -565,7 +560,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen //as a last resort try to select attached panels not in stack for (CardPanel p : panel.getAttachedPanels()) { if (p.getStack() != stack) { //ensure same panel not checked more than once - if (selectCard(p, triggerEvent, selectOtherCardsInStack)) { + if (selectCard(p, triggerEvent, selectEntireStack)) { return true; } } diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index 42101c07799..fda70f4cec3 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -373,7 +373,7 @@ public class Forge implements ApplicationListener { private static class MainInputProcessor extends FGestureAdapter { private static final ArrayList potentialListeners = new ArrayList(); private static char lastKeyTyped; - private static boolean keyTyped; + private static boolean keyTyped, shiftKeyDown; @Override public boolean keyDown(int keyCode) { @@ -381,6 +381,9 @@ public class Forge implements ApplicationListener { showMenu(); return true; } + if (keyCode == Keys.SHIFT_LEFT || keyCode == Keys.SHIFT_RIGHT) { + shiftKeyDown = true; + } if (keyInputAdapter == null) { if (KeyInputAdapter.isModifierKey(keyCode)) { return false; //don't process modifiers keys for unknown adapter @@ -401,6 +404,9 @@ public class Forge implements ApplicationListener { @Override public boolean keyUp(int keyCode) { keyTyped = false; //reset on keyUp + if (keyCode == Keys.SHIFT_LEFT || keyCode == Keys.SHIFT_RIGHT) { + shiftKeyDown = false; + } if (keyInputAdapter != null) { return keyInputAdapter.keyUp(keyCode); } @@ -496,6 +502,9 @@ public class Forge implements ApplicationListener { @Override public boolean tap(float x, float y, int count) { + if (shiftKeyDown && twoFingerTap(x, y, count)) { + return true; //give two finger tap logic a chance to handle Shift+click + } try { for (FDisplayObject listener : potentialListeners) { if (listener.tap(listener.screenToLocalX(x), listener.screenToLocalY(y), count)) { @@ -510,6 +519,22 @@ public class Forge implements ApplicationListener { } } + @Override + public boolean twoFingerTap(float x, float y, int count) { + try { + for (FDisplayObject listener : potentialListeners) { + if (listener.twoFingerTap(listener.screenToLocalX(x), listener.screenToLocalY(y), count)) { + return true; + } + } + return false; + } + catch (Exception ex) { + BugReporter.reportException(ex); + return true; + } + } + @Override public boolean fling(float velocityX, float velocityY) { try { diff --git a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java index b1816c45da5..07edb4e1478 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java @@ -260,11 +260,10 @@ public abstract class VCardDisplayArea extends VDisplayArea { @Override public boolean tap(float x, float y, int count) { if (renderedCardContains(x, y)) { - final boolean selectOtherCardsInStack = (count % 2 == 0); ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown @Override public void run() { - if (!selectCard(selectOtherCardsInStack)) { + if (!selectCard(false)) { //if no cards in stack can be selected, just show zoom/details for card CardZoom.show(getCard()); } @@ -275,17 +274,31 @@ public abstract class VCardDisplayArea extends VDisplayArea { return false; } - public boolean selectCard(boolean selectOtherCardsInStack) { - if (MatchUtil.getHumanController().selectCard(getCard(), getOtherCardsToSelect(selectOtherCardsInStack), null)) { + @Override + public boolean twoFingerTap(float x, float y, int count) { + if (renderedCardContains(x, y)) { + ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown + @Override + public void run() { + selectCard(true); + } + }); + return true; + } + return false; + } + + public boolean selectCard(boolean selectEntireStack) { + if (MatchUtil.getHumanController().selectCard(getCard(), getOtherCardsToSelect(selectEntireStack), null)) { return true; } //if panel can't do anything with card selection, try selecting previous panel in stack - if (prevPanelInStack != null && prevPanelInStack.selectCard(selectOtherCardsInStack)) { + if (prevPanelInStack != null && prevPanelInStack.selectCard(selectEntireStack)) { return true; } //as a last resort try to select attached panels for (CardAreaPanel panel : attachedPanels) { - if (panel.selectCard(selectOtherCardsInStack)) { + if (panel.selectCard(selectEntireStack)) { return true; } } diff --git a/forge-gui-mobile/src/forge/toolbox/FDisplayObject.java b/forge-gui-mobile/src/forge/toolbox/FDisplayObject.java index 15b0b904d29..c1a3a856c3e 100644 --- a/forge-gui-mobile/src/forge/toolbox/FDisplayObject.java +++ b/forge-gui-mobile/src/forge/toolbox/FDisplayObject.java @@ -131,6 +131,10 @@ public abstract class FDisplayObject { return false; } + public boolean twoFingerTap(float x, float y, int count) { + return false; + } + public boolean fling(float velocityX, float velocityY) { return false; } diff --git a/forge-gui-mobile/src/forge/toolbox/FGestureAdapter.java b/forge-gui-mobile/src/forge/toolbox/FGestureAdapter.java index 7a5841f45b8..ae604470e0d 100644 --- a/forge-gui-mobile/src/forge/toolbox/FGestureAdapter.java +++ b/forge-gui-mobile/src/forge/toolbox/FGestureAdapter.java @@ -15,6 +15,7 @@ public abstract class FGestureAdapter extends InputAdapter { public abstract boolean longPress(float x, float y); public abstract boolean release(float x, float y); public abstract boolean tap(float x, float y, int count); + public abstract boolean twoFingerTap(float x, float y, int count); public abstract boolean fling(float velocityX, float velocityY); public abstract boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical); public abstract boolean panStop(float x, float y);