diff --git a/.gitattributes b/.gitattributes index af5c50b2df9..bd16180c09b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16033,7 +16033,6 @@ forge-m-base/src/forge/screens/quest/QuestScreen.java -text forge-m-base/src/forge/screens/sealed/SealedScreen.java -text forge-m-base/src/forge/screens/settings/SettingsScreen.java -text forge-m-base/src/forge/toolbox/FButton.java -text -forge-m-base/src/forge/toolbox/FComboBox.java -text forge-m-base/src/forge/toolbox/FContainer.java -text forge-m-base/src/forge/toolbox/FDisplayObject.java -text forge-m-base/src/forge/toolbox/FLabel.java -text diff --git a/forge-m-base/src/forge/Forge.java b/forge-m-base/src/forge/Forge.java index 957c7ba9e5c..5a385803d0e 100644 --- a/forge-m-base/src/forge/Forge.java +++ b/forge-m-base/src/forge/Forge.java @@ -29,8 +29,6 @@ import forge.screens.SplashScreen; import forge.screens.home.HomeScreen; import forge.toolbox.FContainer; import forge.toolbox.FDisplayObject; -import forge.toolbox.FProgressBar; -import forge.utils.Constants; public class Forge implements ApplicationListener { private static Forge game; @@ -59,7 +57,7 @@ public class Forge implements ApplicationListener { FSkin.loadLight("journeyman", splashScreen); // Loads card database on background thread (using progress bar to report progress) - new Thread(new Runnable() { + /*new Thread(new Runnable() { @Override public void run() { final FProgressBar bar = splashScreen.getProgressBar(); @@ -98,7 +96,8 @@ public class Forge implements ApplicationListener { } }); } - }).start(); + }).start();*/ + afterDbLoaded(); } private void afterDbLoaded() { @@ -190,7 +189,7 @@ public class Forge implements ApplicationListener { @Override public boolean touchUp(float x, float y, int pointer, int button) { for (FDisplayObject listener : potentialListeners) { - if (listener.touchUp(x, y)) { + if (listener.touchUp(listener.screenToLocalX(x), listener.screenToLocalY(y))) { break; } } @@ -206,7 +205,7 @@ public class Forge implements ApplicationListener { currentScreen.buildTouchListeners(x, y, potentialListeners); } for (FDisplayObject listener : potentialListeners) { - if (listener.touchDown(x, y)) { + if (listener.touchDown(listener.screenToLocalX(x), listener.screenToLocalY(y))) { return true; } } @@ -216,7 +215,7 @@ public class Forge implements ApplicationListener { @Override public boolean tap(float x, float y, int count, int button) { for (FDisplayObject listener : potentialListeners) { - if (listener.tap(x, y, count)) { + if (listener.tap(listener.screenToLocalX(x), listener.screenToLocalY(y), count)) { return true; } } @@ -226,7 +225,7 @@ public class Forge implements ApplicationListener { @Override public boolean longPress(float x, float y) { for (FDisplayObject listener : potentialListeners) { - if (listener.longPress(x, y)) { + if (listener.longPress(listener.screenToLocalX(x), listener.screenToLocalY(y))) { return true; } } @@ -246,7 +245,7 @@ public class Forge implements ApplicationListener { @Override public boolean pan(float x, float y, float deltaX, float deltaY) { for (FDisplayObject listener : potentialListeners) { - if (listener.pan(x, y, deltaX, deltaY)) { + if (listener.pan(listener.screenToLocalX(x), listener.screenToLocalY(y), deltaX, deltaY)) { return true; } } @@ -256,7 +255,7 @@ public class Forge implements ApplicationListener { @Override public boolean panStop(float x, float y, int pointer, int button) { for (FDisplayObject listener : potentialListeners) { - if (listener.panStop(x, y)) { + if (listener.panStop(listener.screenToLocalX(x), listener.screenToLocalY(y))) { return true; } } @@ -320,6 +319,7 @@ public class Forge implements ApplicationListener { final Rectangle parentBounds = bounds; bounds = new Rectangle(parentBounds.x + displayObj.getLeft(), parentBounds.y + displayObj.getTop(), displayObj.getWidth(), displayObj.getHeight()); + displayObj.setScreenPosition(bounds.x, bounds.y); if (bounds.overlaps(parentBounds)) { //avoid drawing object if it's not within visible region displayObj.draw(this); diff --git a/forge-m-base/src/forge/screens/settings/SettingsScreen.java b/forge-m-base/src/forge/screens/settings/SettingsScreen.java index 6c8562433e3..dd98eaa86a5 100644 --- a/forge-m-base/src/forge/screens/settings/SettingsScreen.java +++ b/forge-m-base/src/forge/screens/settings/SettingsScreen.java @@ -1,82 +1,25 @@ package forge.screens.settings; -import java.util.ArrayList; -import java.util.List; - -import forge.assets.FSkin; import forge.screens.FScreen; -import forge.toolbox.FComboBox; -import forge.toolbox.FContainer; -import forge.toolbox.FLabel; -import forge.toolbox.FScrollPane; +import forge.toolbox.FList; public class SettingsScreen extends FScreen { - private static final float INSETS_FACTOR = 0.025f; private static final float GAP_Y_FACTOR = 0.01f; - private final FScrollPane scroller = add(new FScrollPane()); - private final List settingPanels = new ArrayList(); + private final FList lstSettings = add(new FList()); public SettingsScreen() { super(true, "Settings", false); - addPanel(new ComboBoxPanel("Theme:", FSkin.getAllSkins(), FSkin.getName())); - } - - private void addPanel(SettingPanel panel) { - scroller.add(panel); - settingPanels.add(panel); + lstSettings.addItem("Theme"); + lstSettings.addItem("Theme4"); + lstSettings.addItem("Theme8"); + //addSetting(new ComboBoxPanel("Theme:", FSkin.getAllSkins(), FSkin.getName())); } @Override protected void doLayout(float startY, float width, float height) { float dy = height * GAP_Y_FACTOR; - scroller.setBounds(0, startY + dy, width, height - startY - dy); - - float x = width * INSETS_FACTOR; - float y = 0; - float panelWidth = width - 2 * x; - float panelHeight; - - for (SettingPanel panel : settingPanels) { - panelHeight = panel.getPreferredHeight(); - panel.setBounds(x, y, panelWidth, panelHeight); - y += panelHeight + dy; - } - } - - private abstract class SettingPanel extends FContainer { - public abstract float getPreferredHeight(); - } - - public class ComboBoxPanel extends SettingPanel { - private final FLabel label; - private final FComboBox comboBox; - - public ComboBoxPanel(String labelText, E[] items, E selectedItem) { - this(labelText, new FComboBox(items), selectedItem); - } - public ComboBoxPanel(String labelText, Iterable items, E selectedItem) { - this(labelText, new FComboBox(items), selectedItem); - } - - private ComboBoxPanel(String labelText, FComboBox comboBox0, E selectedItem) { - label = add(new FLabel.Builder().text(labelText).build()); - comboBox = add(comboBox0); - label.setHeight(FComboBox.PREFERRED_HEIGHT - 6); - comboBox.setHeight(FComboBox.PREFERRED_HEIGHT); - comboBox.setSelectedItem(selectedItem); - } - - @Override - protected void doLayout(float width, float height) { - label.setBounds(0, 0, width, label.getHeight()); - comboBox.setBounds(0, label.getHeight(), width, comboBox.getHeight()); - } - - @Override - public float getPreferredHeight() { - return label.getHeight() + comboBox.getHeight(); - } + lstSettings.setBounds(0, startY + dy, width, height - startY - dy); } } diff --git a/forge-m-base/src/forge/toolbox/FComboBox.java b/forge-m-base/src/forge/toolbox/FComboBox.java deleted file mode 100644 index d5ef65d1b8a..00000000000 --- a/forge-m-base/src/forge/toolbox/FComboBox.java +++ /dev/null @@ -1,112 +0,0 @@ -package forge.toolbox; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment; -import forge.Forge.Graphics; -import forge.assets.FSkinColor; -import forge.assets.FSkinFont; -import forge.assets.FSkinColor.Colors; -import forge.utils.Utils; - -public class FComboBox extends FDisplayObject { - public static final float PREFERRED_HEIGHT = Utils.AVG_FINGER_HEIGHT * 0.7f; - - private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final FSkinColor BACK_COLOR = FSkinColor.get(Colors.CLR_THEME2); - private static final FSkinColor BORDER_COLOR = FORE_COLOR.getContrastColor(40); - - private final List items = new ArrayList(); - private int selectedIndex; - private HAlignment alignment; - private FSkinFont font; - - public FComboBox() { - initialize(); - } - public FComboBox(E[] itemArray) { - for (E item : itemArray) { - items.add(item); - } - initialize(); - } - public FComboBox(Iterable items0) { - for (E item : items0) { - items.add(item); - } - initialize(); - } - - private void initialize() { - selectedIndex = items.isEmpty() ? -1 : 0; - font = FSkinFont.get(12); - alignment = HAlignment.LEFT; - } - - public void addItem(E item) { - if (items.isEmpty()) { - selectedIndex = 0; //select item if no items previously - } - items.add(item); - } - - public void removeItem(E item) { - if (items.remove(item)) { - if (selectedIndex >= items.size()) { - selectedIndex = items.size() - 1; - } - } - } - - public int getItemCount() { - return items.size(); - } - - public E getSelectedItem() { - if (selectedIndex >= 0) { - return items.get(selectedIndex); - } - return null; - } - - public void setSelectedItem(E item) { - int index = items.indexOf(item); - if (index >= 0) { - selectedIndex = index; - } - } - - public HAlignment getAlignment() { - return alignment; - } - - public void setAlignment(HAlignment alignment0) { - alignment = alignment0; - } - - public boolean tap(float x, float y, int count) { - return true; - } - - @Override - public void draw(Graphics g) { - float w = getWidth(); - float h = getHeight(); - - g.fillRect(BACK_COLOR, 0, 0, w, h); - g.drawRect(BORDER_COLOR, 0, 0, w, h); - - float shapeWidth = PREFERRED_HEIGHT / 3; - float shapeHeight = shapeWidth; - float x = w - 2 * (shapeWidth - 1); - float y = h / 2 - 1; - float insetX = 4; - g.fillTriangle(FORE_COLOR, x, y, x + shapeWidth, y, x + (shapeWidth / 2), y + (shapeHeight / 2)); - - E selectedItem = getSelectedItem(); - if (selectedItem != null) { - g.drawText(selectedItem.toString(), font, FORE_COLOR, insetX, 0, x - 2 * insetX, h, false, alignment, true); - } - } -} diff --git a/forge-m-base/src/forge/toolbox/FContainer.java b/forge-m-base/src/forge/toolbox/FContainer.java index 50e9e5149bb..d24bc5b4273 100644 --- a/forge-m-base/src/forge/toolbox/FContainer.java +++ b/forge-m-base/src/forge/toolbox/FContainer.java @@ -58,13 +58,17 @@ public abstract class FContainer extends FDisplayObject { } } + public void revalidate() { + doLayout(getWidth(), getHeight()); + } + protected abstract void doLayout(float width, float height); @Override - public final void buildTouchListeners(float x, float y, ArrayList listeners) { - if (isEnabled() && contains(x, y)) { + public final void buildTouchListeners(float screenX, float screenY, ArrayList listeners) { + if (isEnabled() && contains(screenToLocalX(screenX), screenToLocalY(screenY))) { for (FDisplayObject child : children) { - child.buildTouchListeners(x, y, listeners); + child.buildTouchListeners(screenX, screenY, listeners); } listeners.add(this); } diff --git a/forge-m-base/src/forge/toolbox/FDisplayObject.java b/forge-m-base/src/forge/toolbox/FDisplayObject.java index edbac63050d..7b3715e0ab9 100644 --- a/forge-m-base/src/forge/toolbox/FDisplayObject.java +++ b/forge-m-base/src/forge/toolbox/FDisplayObject.java @@ -11,6 +11,7 @@ public abstract class FDisplayObject { private boolean visible = true; private boolean enabled = true; private final Rectangle bounds = new Rectangle(); + private final Vector2 screenPosition = new Vector2(); public void setPosition(float x, float y) { bounds.setPosition(x, y); @@ -55,6 +56,26 @@ public abstract class FDisplayObject { return visible && bounds.contains(x, y); } + public Vector2 getScreenPosition() { + return screenPosition; + } + public void setScreenPosition(float x, float y) { //only call from Graphics when drawn + screenPosition.set(x, y); + } + + public float screenToLocalX(float x) { + return x - screenPosition.x + bounds.x; + } + public float screenToLocalY(float y) { + return y - screenPosition.y + bounds.y; + } + public float localToScreenX(float x) { + return x - bounds.x + screenPosition.x; + } + public float localToScreenY(float y) { + return y - bounds.y + screenPosition.y; + } + public boolean isEnabled() { return enabled; } @@ -71,8 +92,8 @@ public abstract class FDisplayObject { public abstract void draw(Graphics g); - public void buildTouchListeners(float x, float y, ArrayList listeners) { - if (enabled && contains(x, y)) { + public void buildTouchListeners(float screenX, float screenY, ArrayList listeners) { + if (enabled && contains(screenToLocalX(screenX), screenToLocalY(screenY))) { listeners.add(this); } } diff --git a/forge-m-base/src/forge/toolbox/FLabel.java b/forge-m-base/src/forge/toolbox/FLabel.java index 969a362f37d..543c76a5235 100644 --- a/forge-m-base/src/forge/toolbox/FLabel.java +++ b/forge-m-base/src/forge/toolbox/FLabel.java @@ -13,7 +13,7 @@ public class FLabel extends FDisplayObject { public static class Builder { //========== Default values for FLabel are set here. private float bldIconScaleFactor = 0.8f; - private int bldFontSize = 12; + private int bldFontSize = 14; private HAlignment bldAlignment = HAlignment.LEFT; private Vector2 bldInsets = new Vector2(0, 0); diff --git a/forge-m-base/src/forge/toolbox/FList.java b/forge-m-base/src/forge/toolbox/FList.java index 91a189a05b5..22c78e70ef0 100644 --- a/forge-m-base/src/forge/toolbox/FList.java +++ b/forge-m-base/src/forge/toolbox/FList.java @@ -2,6 +2,8 @@ package forge.toolbox; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment; @@ -12,14 +14,13 @@ import forge.assets.FSkinColor.Colors; import forge.utils.Utils; public class FList extends FScrollPane { - public static final float PREFERRED_HEIGHT = Utils.AVG_FINGER_HEIGHT * 0.7f; - + private static final float INSETS_FACTOR = 0.025f; + private static final float GROUP_HEADER_HEIGHT = Utils.AVG_FINGER_HEIGHT * 0.7f; private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final FSkinColor BACK_COLOR = FSkinColor.get(Colors.CLR_THEME2); - private static final FSkinColor BORDER_COLOR = FORE_COLOR.getContrastColor(40); + private static final FSkinColor PRESSED_COLOR = FSkinColor.get(Colors.CLR_THEME2).alphaColor(0.75f); + private static final FSkinColor LINE_COLOR = FORE_COLOR.alphaColor(0.5f); - private final List items = new ArrayList(); - private int selectedIndex; + private final Map groups = new TreeMap(); private FSkinFont font; private ListItemRenderer renderer; @@ -28,68 +29,48 @@ public class FList extends FScrollPane { } public FList(E[] itemArray) { for (E item : itemArray) { - items.add(add(new ListItem(item))); + addItem(item); } initialize(); } public FList(Iterable items0) { for (E item : items0) { - items.add(new ListItem(item)); + addItem(item); } initialize(); } private void initialize() { - selectedIndex = items.isEmpty() ? -1 : 0; - font = FSkinFont.get(12); + font = FSkinFont.get(14); renderer = new DefaultListItemRenderer(); } public void addItem(E item) { - if (items.isEmpty()) { - selectedIndex = 0; //select item if no items previously - } - items.add(add(new ListItem(item))); + addItem(item, ""); } - - private int getIndexOfItem(E item) { - for (int i = 0; i < items.size(); i++) { - if (items.get(i).value == item) { - return i; - } + public void addItem(E item, String groupName) { + ListGroup group = groups.get(groupName); + if (group == null) { + group = add(new ListGroup(groupName)); + groups.put(groupName, group); } - return -1; + group.addItem(new ListItem(item)); } public void removeItem(E item) { - int index = getIndexOfItem(item); - if (index >= 0) { - remove(items.get(index)); - items.remove(index); - if (selectedIndex >= items.size()) { - selectedIndex = items.size() - 1; + for (ListGroup group : groups.values()) { + for (ListItem groupItem : group.items) { + if (groupItem.value == item) { + group.removeItem(groupItem); + if (group.items.isEmpty()) { + groups.remove(group.getName()); + } + return; + } } } } - public int getItemCount() { - return items.size(); - } - - public E getSelectedItem() { - if (selectedIndex >= 0) { - return items.get(selectedIndex).value; - } - return null; - } - - public void setSelectedItem(E item) { - int index = getIndexOfItem(item); - if (index >= 0) { - selectedIndex = index; - } - } - public void setListItemRenderer(ListItemRenderer renderer0) { renderer = renderer0; } @@ -97,50 +78,140 @@ public class FList extends FScrollPane { @Override protected void doLayout(float width, float height) { float y = 0; - float itemHeight = renderer.getItemHeight(); + float groupHeight; - for (ListItem item : items) { - item.setBounds(0, y, width, itemHeight); - y += itemHeight; + for (ListGroup group : groups.values()) { + groupHeight = group.getPreferredHeight(); + group.setBounds(0, y, width, groupHeight); + y += groupHeight; } } - @Override - protected void drawBackground(Graphics g) { - float w = getWidth(); - float h = getHeight(); + private class ListGroup extends FContainer { + private final FLabel header; + private final List items = new ArrayList(); - g.fillRect(BACK_COLOR, 0, 0, w, h); - g.drawRect(BORDER_COLOR, 0, 0, w, h); + private boolean isCollapsed; + + private ListGroup(String name0) { + if (name0.isEmpty()) { + header = null; + } + else { + header = new FLabel.ButtonBuilder().text(name0).command(new Runnable() { + @Override + public void run() { + isCollapsed = !isCollapsed; + FList.this.revalidate(); + } + }).build(); + } + } + + public String getName() { + return header == null ? null : header.getText(); + } + + public void addItem(ListItem item) { + items.add(item); + add(item); + } + + public boolean removeItem(ListItem item) { + if (items.remove(item)) { + remove(item); + return true; + } + return false; + } + + public float getPreferredHeight() { + float height = 0; + if (header != null) { + height += GROUP_HEADER_HEIGHT; + } + if (!isCollapsed) { + height += (renderer.getItemHeight() + 1) * items.size(); + } + return height; + } + + @Override + protected void doLayout(float width, float height) { + float y = 0; + if (header != null) { + header.setBounds(0, y, width, GROUP_HEADER_HEIGHT); + y += GROUP_HEADER_HEIGHT; + } + + float itemHeight = renderer.getItemHeight() + 1; //account for bottom border + + for (ListItem item : items) { + item.setBounds(0, y, width, itemHeight); + y += itemHeight; + } + } } private class ListItem extends FDisplayObject { private final E value; + private boolean pressed; private ListItem(E value0) { value = value0; } + public boolean touchDown(float x, float y) { + pressed = true; + return true; + } + + public boolean touchUp(float x, float y) { + pressed = false; + return true; + } + + public boolean tap(float x, float y, int count) { + return renderer.tap(value, x, y, count); + } + @Override public final void draw(Graphics g) { - renderer.drawValue(g, value, font, FORE_COLOR, getWidth(), getHeight()); + float w = getWidth(); + float h = renderer.getItemHeight(); + + if (pressed) { + g.fillRect(PRESSED_COLOR, 0, 0, w, h); + } + + renderer.drawValue(g, value, font, FORE_COLOR, w, h); + + float y = h + 1; + g.drawLine(LINE_COLOR, 0, y, w, y); } } public abstract class ListItemRenderer { public abstract float getItemHeight(); + public abstract boolean tap(E value, float x, float y, int count); public abstract void drawValue(Graphics g, E value, FSkinFont font, FSkinColor foreColor, float width, float height); } public class DefaultListItemRenderer extends ListItemRenderer { @Override public float getItemHeight() { - return 25; + return Utils.AVG_FINGER_HEIGHT; + } + + @Override + public boolean tap(E value, float x, float y, int count) { + return false; } @Override public void drawValue(Graphics g, E value, FSkinFont font, FSkinColor color, float width, float height) { - g.drawText(value.toString(), font, color, 0, 0, width, height, false, HAlignment.LEFT, true); + float x = width * INSETS_FACTOR; + g.drawText(value.toString(), font, color, x, 0, width - 2 * x, height, false, HAlignment.LEFT, true); } } } diff --git a/forge-m-base/src/forge/toolbox/FOverlay.java b/forge-m-base/src/forge/toolbox/FOverlay.java index eca4d2623b6..c17fd1b5ef4 100644 --- a/forge-m-base/src/forge/toolbox/FOverlay.java +++ b/forge-m-base/src/forge/toolbox/FOverlay.java @@ -7,7 +7,7 @@ import forge.assets.FSkinColor; import forge.assets.FSkinColor.Colors; public class FOverlay extends FContainer { - private static final FSkinColor BACKDROP_COLOR = FSkinColor.get(Colors.CLR_OVERLAY).alphaColor(120); + private static final FSkinColor BACKDROP_COLOR = FSkinColor.get(Colors.CLR_OVERLAY).alphaColor(0.5f); private static final FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS); private static final float CORNER_RADIUS = 10; private static final Stack overlays = new Stack();