mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 18:58:00 +00:00
Flesh out FList and support nested containers
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -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/sealed/SealedScreen.java -text
|
||||||
forge-m-base/src/forge/screens/settings/SettingsScreen.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/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/FContainer.java -text
|
||||||
forge-m-base/src/forge/toolbox/FDisplayObject.java -text
|
forge-m-base/src/forge/toolbox/FDisplayObject.java -text
|
||||||
forge-m-base/src/forge/toolbox/FLabel.java -text
|
forge-m-base/src/forge/toolbox/FLabel.java -text
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ import forge.screens.SplashScreen;
|
|||||||
import forge.screens.home.HomeScreen;
|
import forge.screens.home.HomeScreen;
|
||||||
import forge.toolbox.FContainer;
|
import forge.toolbox.FContainer;
|
||||||
import forge.toolbox.FDisplayObject;
|
import forge.toolbox.FDisplayObject;
|
||||||
import forge.toolbox.FProgressBar;
|
|
||||||
import forge.utils.Constants;
|
|
||||||
|
|
||||||
public class Forge implements ApplicationListener {
|
public class Forge implements ApplicationListener {
|
||||||
private static Forge game;
|
private static Forge game;
|
||||||
@@ -59,7 +57,7 @@ public class Forge implements ApplicationListener {
|
|||||||
FSkin.loadLight("journeyman", splashScreen);
|
FSkin.loadLight("journeyman", splashScreen);
|
||||||
|
|
||||||
// Loads card database on background thread (using progress bar to report progress)
|
// Loads card database on background thread (using progress bar to report progress)
|
||||||
new Thread(new Runnable() {
|
/*new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final FProgressBar bar = splashScreen.getProgressBar();
|
final FProgressBar bar = splashScreen.getProgressBar();
|
||||||
@@ -98,7 +96,8 @@ public class Forge implements ApplicationListener {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();*/
|
||||||
|
afterDbLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void afterDbLoaded() {
|
private void afterDbLoaded() {
|
||||||
@@ -190,7 +189,7 @@ public class Forge implements ApplicationListener {
|
|||||||
@Override
|
@Override
|
||||||
public boolean touchUp(float x, float y, int pointer, int button) {
|
public boolean touchUp(float x, float y, int pointer, int button) {
|
||||||
for (FDisplayObject listener : potentialListeners) {
|
for (FDisplayObject listener : potentialListeners) {
|
||||||
if (listener.touchUp(x, y)) {
|
if (listener.touchUp(listener.screenToLocalX(x), listener.screenToLocalY(y))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,7 +205,7 @@ public class Forge implements ApplicationListener {
|
|||||||
currentScreen.buildTouchListeners(x, y, potentialListeners);
|
currentScreen.buildTouchListeners(x, y, potentialListeners);
|
||||||
}
|
}
|
||||||
for (FDisplayObject listener : potentialListeners) {
|
for (FDisplayObject listener : potentialListeners) {
|
||||||
if (listener.touchDown(x, y)) {
|
if (listener.touchDown(listener.screenToLocalX(x), listener.screenToLocalY(y))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,7 +215,7 @@ public class Forge implements ApplicationListener {
|
|||||||
@Override
|
@Override
|
||||||
public boolean tap(float x, float y, int count, int button) {
|
public boolean tap(float x, float y, int count, int button) {
|
||||||
for (FDisplayObject listener : potentialListeners) {
|
for (FDisplayObject listener : potentialListeners) {
|
||||||
if (listener.tap(x, y, count)) {
|
if (listener.tap(listener.screenToLocalX(x), listener.screenToLocalY(y), count)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,7 +225,7 @@ public class Forge implements ApplicationListener {
|
|||||||
@Override
|
@Override
|
||||||
public boolean longPress(float x, float y) {
|
public boolean longPress(float x, float y) {
|
||||||
for (FDisplayObject listener : potentialListeners) {
|
for (FDisplayObject listener : potentialListeners) {
|
||||||
if (listener.longPress(x, y)) {
|
if (listener.longPress(listener.screenToLocalX(x), listener.screenToLocalY(y))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,7 +245,7 @@ public class Forge implements ApplicationListener {
|
|||||||
@Override
|
@Override
|
||||||
public boolean pan(float x, float y, float deltaX, float deltaY) {
|
public boolean pan(float x, float y, float deltaX, float deltaY) {
|
||||||
for (FDisplayObject listener : potentialListeners) {
|
for (FDisplayObject listener : potentialListeners) {
|
||||||
if (listener.pan(x, y, deltaX, deltaY)) {
|
if (listener.pan(listener.screenToLocalX(x), listener.screenToLocalY(y), deltaX, deltaY)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -256,7 +255,7 @@ public class Forge implements ApplicationListener {
|
|||||||
@Override
|
@Override
|
||||||
public boolean panStop(float x, float y, int pointer, int button) {
|
public boolean panStop(float x, float y, int pointer, int button) {
|
||||||
for (FDisplayObject listener : potentialListeners) {
|
for (FDisplayObject listener : potentialListeners) {
|
||||||
if (listener.panStop(x, y)) {
|
if (listener.panStop(listener.screenToLocalX(x), listener.screenToLocalY(y))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,6 +319,7 @@ public class Forge implements ApplicationListener {
|
|||||||
|
|
||||||
final Rectangle parentBounds = bounds;
|
final Rectangle parentBounds = bounds;
|
||||||
bounds = new Rectangle(parentBounds.x + displayObj.getLeft(), parentBounds.y + displayObj.getTop(), displayObj.getWidth(), displayObj.getHeight());
|
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
|
if (bounds.overlaps(parentBounds)) { //avoid drawing object if it's not within visible region
|
||||||
displayObj.draw(this);
|
displayObj.draw(this);
|
||||||
|
|||||||
@@ -1,82 +1,25 @@
|
|||||||
package forge.screens.settings;
|
package forge.screens.settings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import forge.assets.FSkin;
|
|
||||||
import forge.screens.FScreen;
|
import forge.screens.FScreen;
|
||||||
import forge.toolbox.FComboBox;
|
import forge.toolbox.FList;
|
||||||
import forge.toolbox.FContainer;
|
|
||||||
import forge.toolbox.FLabel;
|
|
||||||
import forge.toolbox.FScrollPane;
|
|
||||||
|
|
||||||
public class SettingsScreen extends FScreen {
|
public class SettingsScreen extends FScreen {
|
||||||
private static final float INSETS_FACTOR = 0.025f;
|
|
||||||
private static final float GAP_Y_FACTOR = 0.01f;
|
private static final float GAP_Y_FACTOR = 0.01f;
|
||||||
|
|
||||||
private final FScrollPane scroller = add(new FScrollPane());
|
private final FList<Object> lstSettings = add(new FList<Object>());
|
||||||
private final List<SettingPanel> settingPanels = new ArrayList<SettingPanel>();
|
|
||||||
|
|
||||||
public SettingsScreen() {
|
public SettingsScreen() {
|
||||||
super(true, "Settings", false);
|
super(true, "Settings", false);
|
||||||
|
|
||||||
addPanel(new ComboBoxPanel<String>("Theme:", FSkin.getAllSkins(), FSkin.getName()));
|
lstSettings.addItem("Theme");
|
||||||
}
|
lstSettings.addItem("Theme4");
|
||||||
|
lstSettings.addItem("Theme8");
|
||||||
private void addPanel(SettingPanel panel) {
|
//addSetting(new ComboBoxPanel<String>("Theme:", FSkin.getAllSkins(), FSkin.getName()));
|
||||||
scroller.add(panel);
|
|
||||||
settingPanels.add(panel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doLayout(float startY, float width, float height) {
|
protected void doLayout(float startY, float width, float height) {
|
||||||
float dy = height * GAP_Y_FACTOR;
|
float dy = height * GAP_Y_FACTOR;
|
||||||
scroller.setBounds(0, startY + dy, width, height - startY - dy);
|
lstSettings.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<E> extends SettingPanel {
|
|
||||||
private final FLabel label;
|
|
||||||
private final FComboBox<E> comboBox;
|
|
||||||
|
|
||||||
public ComboBoxPanel(String labelText, E[] items, E selectedItem) {
|
|
||||||
this(labelText, new FComboBox<E>(items), selectedItem);
|
|
||||||
}
|
|
||||||
public ComboBoxPanel(String labelText, Iterable<E> items, E selectedItem) {
|
|
||||||
this(labelText, new FComboBox<E>(items), selectedItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ComboBoxPanel(String labelText, FComboBox<E> 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<E> 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<E> items = new ArrayList<E>();
|
|
||||||
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<E> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -58,13 +58,17 @@ public abstract class FContainer extends FDisplayObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void revalidate() {
|
||||||
|
doLayout(getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract void doLayout(float width, float height);
|
protected abstract void doLayout(float width, float height);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void buildTouchListeners(float x, float y, ArrayList<FDisplayObject> listeners) {
|
public final void buildTouchListeners(float screenX, float screenY, ArrayList<FDisplayObject> listeners) {
|
||||||
if (isEnabled() && contains(x, y)) {
|
if (isEnabled() && contains(screenToLocalX(screenX), screenToLocalY(screenY))) {
|
||||||
for (FDisplayObject child : children) {
|
for (FDisplayObject child : children) {
|
||||||
child.buildTouchListeners(x, y, listeners);
|
child.buildTouchListeners(screenX, screenY, listeners);
|
||||||
}
|
}
|
||||||
listeners.add(this);
|
listeners.add(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public abstract class FDisplayObject {
|
|||||||
private boolean visible = true;
|
private boolean visible = true;
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
private final Rectangle bounds = new Rectangle();
|
private final Rectangle bounds = new Rectangle();
|
||||||
|
private final Vector2 screenPosition = new Vector2();
|
||||||
|
|
||||||
public void setPosition(float x, float y) {
|
public void setPosition(float x, float y) {
|
||||||
bounds.setPosition(x, y);
|
bounds.setPosition(x, y);
|
||||||
@@ -55,6 +56,26 @@ public abstract class FDisplayObject {
|
|||||||
return visible && bounds.contains(x, y);
|
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() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
@@ -71,8 +92,8 @@ public abstract class FDisplayObject {
|
|||||||
|
|
||||||
public abstract void draw(Graphics g);
|
public abstract void draw(Graphics g);
|
||||||
|
|
||||||
public void buildTouchListeners(float x, float y, ArrayList<FDisplayObject> listeners) {
|
public void buildTouchListeners(float screenX, float screenY, ArrayList<FDisplayObject> listeners) {
|
||||||
if (enabled && contains(x, y)) {
|
if (enabled && contains(screenToLocalX(screenX), screenToLocalY(screenY))) {
|
||||||
listeners.add(this);
|
listeners.add(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class FLabel extends FDisplayObject {
|
|||||||
public static class Builder {
|
public static class Builder {
|
||||||
//========== Default values for FLabel are set here.
|
//========== Default values for FLabel are set here.
|
||||||
private float bldIconScaleFactor = 0.8f;
|
private float bldIconScaleFactor = 0.8f;
|
||||||
private int bldFontSize = 12;
|
private int bldFontSize = 14;
|
||||||
private HAlignment bldAlignment = HAlignment.LEFT;
|
private HAlignment bldAlignment = HAlignment.LEFT;
|
||||||
private Vector2 bldInsets = new Vector2(0, 0);
|
private Vector2 bldInsets = new Vector2(0, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package forge.toolbox;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
|
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
|
||||||
|
|
||||||
@@ -12,14 +14,13 @@ import forge.assets.FSkinColor.Colors;
|
|||||||
import forge.utils.Utils;
|
import forge.utils.Utils;
|
||||||
|
|
||||||
public class FList<E> extends FScrollPane {
|
public class FList<E> 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 FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT);
|
||||||
private static final FSkinColor BACK_COLOR = FSkinColor.get(Colors.CLR_THEME2);
|
private static final FSkinColor PRESSED_COLOR = FSkinColor.get(Colors.CLR_THEME2).alphaColor(0.75f);
|
||||||
private static final FSkinColor BORDER_COLOR = FORE_COLOR.getContrastColor(40);
|
private static final FSkinColor LINE_COLOR = FORE_COLOR.alphaColor(0.5f);
|
||||||
|
|
||||||
private final List<ListItem> items = new ArrayList<ListItem>();
|
private final Map<String, ListGroup> groups = new TreeMap<String, ListGroup>();
|
||||||
private int selectedIndex;
|
|
||||||
private FSkinFont font;
|
private FSkinFont font;
|
||||||
private ListItemRenderer renderer;
|
private ListItemRenderer renderer;
|
||||||
|
|
||||||
@@ -28,68 +29,48 @@ public class FList<E> extends FScrollPane {
|
|||||||
}
|
}
|
||||||
public FList(E[] itemArray) {
|
public FList(E[] itemArray) {
|
||||||
for (E item : itemArray) {
|
for (E item : itemArray) {
|
||||||
items.add(add(new ListItem(item)));
|
addItem(item);
|
||||||
}
|
}
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
public FList(Iterable<E> items0) {
|
public FList(Iterable<E> items0) {
|
||||||
for (E item : items0) {
|
for (E item : items0) {
|
||||||
items.add(new ListItem(item));
|
addItem(item);
|
||||||
}
|
}
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialize() {
|
private void initialize() {
|
||||||
selectedIndex = items.isEmpty() ? -1 : 0;
|
font = FSkinFont.get(14);
|
||||||
font = FSkinFont.get(12);
|
|
||||||
renderer = new DefaultListItemRenderer();
|
renderer = new DefaultListItemRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addItem(E item) {
|
public void addItem(E item) {
|
||||||
if (items.isEmpty()) {
|
addItem(item, "");
|
||||||
selectedIndex = 0; //select item if no items previously
|
|
||||||
}
|
|
||||||
items.add(add(new ListItem(item)));
|
|
||||||
}
|
}
|
||||||
|
public void addItem(E item, String groupName) {
|
||||||
private int getIndexOfItem(E item) {
|
ListGroup group = groups.get(groupName);
|
||||||
for (int i = 0; i < items.size(); i++) {
|
if (group == null) {
|
||||||
if (items.get(i).value == item) {
|
group = add(new ListGroup(groupName));
|
||||||
return i;
|
groups.put(groupName, group);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return -1;
|
group.addItem(new ListItem(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeItem(E item) {
|
public void removeItem(E item) {
|
||||||
int index = getIndexOfItem(item);
|
for (ListGroup group : groups.values()) {
|
||||||
if (index >= 0) {
|
for (ListItem groupItem : group.items) {
|
||||||
remove(items.get(index));
|
if (groupItem.value == item) {
|
||||||
items.remove(index);
|
group.removeItem(groupItem);
|
||||||
if (selectedIndex >= items.size()) {
|
if (group.items.isEmpty()) {
|
||||||
selectedIndex = items.size() - 1;
|
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) {
|
public void setListItemRenderer(ListItemRenderer renderer0) {
|
||||||
renderer = renderer0;
|
renderer = renderer0;
|
||||||
}
|
}
|
||||||
@@ -97,50 +78,140 @@ public class FList<E> extends FScrollPane {
|
|||||||
@Override
|
@Override
|
||||||
protected void doLayout(float width, float height) {
|
protected void doLayout(float width, float height) {
|
||||||
float y = 0;
|
float y = 0;
|
||||||
float itemHeight = renderer.getItemHeight();
|
float groupHeight;
|
||||||
|
|
||||||
for (ListItem item : items) {
|
for (ListGroup group : groups.values()) {
|
||||||
item.setBounds(0, y, width, itemHeight);
|
groupHeight = group.getPreferredHeight();
|
||||||
y += itemHeight;
|
group.setBounds(0, y, width, groupHeight);
|
||||||
|
y += groupHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private class ListGroup extends FContainer {
|
||||||
protected void drawBackground(Graphics g) {
|
private final FLabel header;
|
||||||
float w = getWidth();
|
private final List<ListItem> items = new ArrayList<ListItem>();
|
||||||
float h = getHeight();
|
|
||||||
|
|
||||||
g.fillRect(BACK_COLOR, 0, 0, w, h);
|
private boolean isCollapsed;
|
||||||
g.drawRect(BORDER_COLOR, 0, 0, w, h);
|
|
||||||
|
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 class ListItem extends FDisplayObject {
|
||||||
private final E value;
|
private final E value;
|
||||||
|
private boolean pressed;
|
||||||
|
|
||||||
private ListItem(E value0) {
|
private ListItem(E value0) {
|
||||||
value = 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
|
@Override
|
||||||
public final void draw(Graphics g) {
|
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 class ListItemRenderer {
|
||||||
public abstract float getItemHeight();
|
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 abstract void drawValue(Graphics g, E value, FSkinFont font, FSkinColor foreColor, float width, float height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DefaultListItemRenderer extends ListItemRenderer {
|
public class DefaultListItemRenderer extends ListItemRenderer {
|
||||||
@Override
|
@Override
|
||||||
public float getItemHeight() {
|
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
|
@Override
|
||||||
public void drawValue(Graphics g, E value, FSkinFont font, FSkinColor color, float width, float height) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import forge.assets.FSkinColor;
|
|||||||
import forge.assets.FSkinColor.Colors;
|
import forge.assets.FSkinColor.Colors;
|
||||||
|
|
||||||
public class FOverlay extends FContainer {
|
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 FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS);
|
||||||
private static final float CORNER_RADIUS = 10;
|
private static final float CORNER_RADIUS = 10;
|
||||||
private static final Stack<FOverlay> overlays = new Stack<FOverlay>();
|
private static final Stack<FOverlay> overlays = new Stack<FOverlay>();
|
||||||
|
|||||||
Reference in New Issue
Block a user