From 10c48cfcf8ea9f8258a16a36a5f311946ac5d877 Mon Sep 17 00:00:00 2001 From: drdev Date: Sat, 17 May 2014 18:10:21 +0000 Subject: [PATCH] Improve zoom support to zero in on focal point --- .../src/forge/screens/match/MatchScreen.java | 42 +++++++++++++++++-- .../src/forge/screens/match/views/VField.java | 10 ++++- .../screens/match/views/VPlayerPanel.java | 8 ++++ .../src/forge/toolbox/FScrollPane.java | 4 +- 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java index 3bf39eef6c5..c506a7e0679 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java @@ -3,6 +3,9 @@ package forge.screens.match; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; + +import org.apache.commons.lang3.tuple.Pair; import com.badlogic.gdx.Input.Keys; @@ -15,6 +18,7 @@ import forge.screens.match.views.VDevMenu; import forge.screens.match.views.VGameMenu; import forge.screens.match.views.VLog; import forge.screens.match.views.VPlayerPanel; +import forge.screens.match.views.VPlayerPanel.InfoTab; import forge.screens.match.views.VPlayers; import forge.screens.match.views.VPrompt; import forge.screens.match.views.VStack; @@ -226,18 +230,48 @@ public class MatchScreen extends FScreen { @Override public boolean zoom(float x, float y, float amount) { + //adjust position for current scroll positions + float oldScrollHeight = getScrollHeight(); y += getScrollTop(); - float yRatioBefore = (y + getScrollTop()) / getScrollHeight(); + + //build map of all horizontal scroll panes and their current scrollWidths and adjusted X values + Map> horzScrollPanes = new HashMap>(); + backupHorzScrollPanes(topPlayerPanel, x, horzScrollPanes); + backupHorzScrollPanes(bottomPlayerPanel, x, horzScrollPanes); extraHeight += amount; if (extraHeight < 0) { extraHeight = 0; } - revalidate(); + revalidate(); //apply change in height to all scroll panes + + //adjust scroll top to keep y position the same + float newScrollHeight = getScrollHeight(); + float yAfter = y * newScrollHeight / oldScrollHeight; + setScrollTop(getScrollTop() + yAfter - y); + + //adjust scroll left of all horizontal scroll panes to keep x position the same + for (Entry> entry : horzScrollPanes.entrySet()) { + FScrollPane horzScrollPane = entry.getKey(); + x = entry.getValue().getRight(); + float oldScrollWidth = entry.getValue().getLeft(); + float newScrollWidth = horzScrollPane.getScrollWidth(); + float xAfter = x * newScrollWidth / oldScrollWidth; + horzScrollPane.setScrollLeft(horzScrollPane.getScrollLeft() + xAfter - x); + } - float yRatioAfter = (y + getScrollTop()) / getScrollHeight(); - return true; } + + private void backupHorzScrollPanes(VPlayerPanel playerPanel, float x, Map> horzScrollPanes) { + backupHorzScrollPane(playerPanel.getField().getRow1(), x, horzScrollPanes); + backupHorzScrollPane(playerPanel.getField().getRow2(), x, horzScrollPanes); + for (InfoTab tab : playerPanel.getTabs()) { + backupHorzScrollPane(tab.getDisplayArea(), x, horzScrollPanes); + } + } + private void backupHorzScrollPane(FScrollPane scrollPane, float x, Map> horzScrollPanes) { + horzScrollPanes.put(scrollPane, Pair.of(scrollPane.getScrollWidth(), x + scrollPane.getScrollLeft())); + } } } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VField.java b/forge-gui-mobile/src/forge/screens/match/views/VField.java index 5f3fdd7824f..7249668b7e3 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VField.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VField.java @@ -171,6 +171,14 @@ public class VField extends FContainer { toPanel.setCard(toPanel.getCard()); } + public FieldRow getRow1() { + return row1; + } + + public FieldRow getRow2() { + return row2; + } + @Override public void clear() { row1.clear(); //clear rows instead of removing the rows @@ -193,7 +201,7 @@ public class VField extends FContainer { row2.setBounds(0, y2, width, cardSize); } - private class FieldRow extends VCardDisplayArea { + public class FieldRow extends VCardDisplayArea { private FieldRow() { setVisible(true); //make visible by default unlike other display areas } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VPlayerPanel.java b/forge-gui-mobile/src/forge/screens/match/views/VPlayerPanel.java index d7051e3ee7f..4a591efe27e 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VPlayerPanel.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VPlayerPanel.java @@ -73,6 +73,10 @@ public class VPlayerPanel extends FContainer { tabs.add(zoneTab); } + public Iterable getTabs() { + return tabs; + } + public InfoTab getSelectedTab() { return selectedTab; } @@ -239,6 +243,10 @@ public class VPlayerPanel extends FContainer { displayArea = displayArea0; } + public VDisplayArea getDisplayArea() { + return displayArea; + } + @Override public boolean tap(float x, float y, int count) { if (selectedTab == this) { diff --git a/forge-gui-mobile/src/forge/toolbox/FScrollPane.java b/forge-gui-mobile/src/forge/toolbox/FScrollPane.java index 51a96394a7c..47983374705 100644 --- a/forge-gui-mobile/src/forge/toolbox/FScrollPane.java +++ b/forge-gui-mobile/src/forge/toolbox/FScrollPane.java @@ -261,12 +261,12 @@ public abstract class FScrollPane extends FContainer { @Override public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { - if (getMaxScrollTop() == 0 && (moreVertical || y < 0 || y >= getHeight() || Math.abs(deltaY) > Math.abs(deltaX))) { + if (getMaxScrollTop() <= 0 && (moreVertical || y < 0 || y >= getHeight() || Math.abs(deltaY) > Math.abs(deltaX))) { //if can't scroll vertically, don't scroll at all if pan is more vertical //or current position is above or below this scroll pane return false; } - if (getMaxScrollLeft() == 0 && (!moreVertical || x < 0 || x >= getWidth() || Math.abs(deltaX) > Math.abs(deltaY))) { + if (getMaxScrollLeft() <= 0 && (!moreVertical || x < 0 || x >= getWidth() || Math.abs(deltaX) > Math.abs(deltaY))) { //if can't scroll horizontally, don't scroll at all if pan is more horizontal //or current position is left or right of this scroll pane return false;