Improve zoom support to zero in on focal point

This commit is contained in:
drdev
2014-05-17 18:10:21 +00:00
parent d19aa2c88a
commit 10c48cfcf8
4 changed files with 57 additions and 7 deletions

View File

@@ -3,6 +3,9 @@ package forge.screens.match;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang3.tuple.Pair;
import com.badlogic.gdx.Input.Keys; 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.VGameMenu;
import forge.screens.match.views.VLog; import forge.screens.match.views.VLog;
import forge.screens.match.views.VPlayerPanel; import forge.screens.match.views.VPlayerPanel;
import forge.screens.match.views.VPlayerPanel.InfoTab;
import forge.screens.match.views.VPlayers; import forge.screens.match.views.VPlayers;
import forge.screens.match.views.VPrompt; import forge.screens.match.views.VPrompt;
import forge.screens.match.views.VStack; import forge.screens.match.views.VStack;
@@ -226,18 +230,48 @@ public class MatchScreen extends FScreen {
@Override @Override
public boolean zoom(float x, float y, float amount) { public boolean zoom(float x, float y, float amount) {
//adjust position for current scroll positions
float oldScrollHeight = getScrollHeight();
y += getScrollTop(); y += getScrollTop();
float yRatioBefore = (y + getScrollTop()) / getScrollHeight();
//build map of all horizontal scroll panes and their current scrollWidths and adjusted X values
Map<FScrollPane, Pair<Float, Float>> horzScrollPanes = new HashMap<FScrollPane, Pair<Float, Float>>();
backupHorzScrollPanes(topPlayerPanel, x, horzScrollPanes);
backupHorzScrollPanes(bottomPlayerPanel, x, horzScrollPanes);
extraHeight += amount; extraHeight += amount;
if (extraHeight < 0) { if (extraHeight < 0) {
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<FScrollPane, Pair<Float, Float>> 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; return true;
} }
private void backupHorzScrollPanes(VPlayerPanel playerPanel, float x, Map<FScrollPane, Pair<Float, Float>> 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<FScrollPane, Pair<Float, Float>> horzScrollPanes) {
horzScrollPanes.put(scrollPane, Pair.of(scrollPane.getScrollWidth(), x + scrollPane.getScrollLeft()));
}
} }
} }

View File

@@ -171,6 +171,14 @@ public class VField extends FContainer {
toPanel.setCard(toPanel.getCard()); toPanel.setCard(toPanel.getCard());
} }
public FieldRow getRow1() {
return row1;
}
public FieldRow getRow2() {
return row2;
}
@Override @Override
public void clear() { public void clear() {
row1.clear(); //clear rows instead of removing the rows row1.clear(); //clear rows instead of removing the rows
@@ -193,7 +201,7 @@ public class VField extends FContainer {
row2.setBounds(0, y2, width, cardSize); row2.setBounds(0, y2, width, cardSize);
} }
private class FieldRow extends VCardDisplayArea { public class FieldRow extends VCardDisplayArea {
private FieldRow() { private FieldRow() {
setVisible(true); //make visible by default unlike other display areas setVisible(true); //make visible by default unlike other display areas
} }

View File

@@ -73,6 +73,10 @@ public class VPlayerPanel extends FContainer {
tabs.add(zoneTab); tabs.add(zoneTab);
} }
public Iterable<InfoTab> getTabs() {
return tabs;
}
public InfoTab getSelectedTab() { public InfoTab getSelectedTab() {
return selectedTab; return selectedTab;
} }
@@ -239,6 +243,10 @@ public class VPlayerPanel extends FContainer {
displayArea = displayArea0; displayArea = displayArea0;
} }
public VDisplayArea getDisplayArea() {
return displayArea;
}
@Override @Override
public boolean tap(float x, float y, int count) { public boolean tap(float x, float y, int count) {
if (selectedTab == this) { if (selectedTab == this) {

View File

@@ -261,12 +261,12 @@ public abstract class FScrollPane extends FContainer {
@Override @Override
public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { 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 //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 //or current position is above or below this scroll pane
return false; 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 //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 //or current position is left or right of this scroll pane
return false; return false;