mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
Improve zoom support to zero in on focal point
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
float yRatioAfter = (y + getScrollTop()) / getScrollHeight();
|
//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);
|
||||||
|
}
|
||||||
|
|
||||||
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()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user