diff --git a/forge-m-base/src/forge/Forge.java b/forge-m-base/src/forge/Forge.java index 727d16a25d2..c6718aded33 100644 --- a/forge-m-base/src/forge/Forge.java +++ b/forge-m-base/src/forge/Forge.java @@ -339,6 +339,7 @@ public class Forge implements ApplicationListener { public static class Graphics { private Rectangle bounds; private int failedClipCount; + private float alphaComposite = 1; private Graphics() { bounds = new Rectangle(0, 0, screenWidth, screenHeight); @@ -388,6 +389,9 @@ public class Forge implements ApplicationListener { if (thickness > 1) { Gdx.gl.glLineWidth(thickness); } + if (alphaComposite < 1) { + color = FSkinColor.alphaColor(color, color.a * alphaComposite); + } boolean needSmoothing = (x1 != x2 && y1 != y2); if (color.a < 1 || needSmoothing) { //enable blending so alpha colored shapes work properly Gdx.gl.glEnable(GL20.GL_BLEND); @@ -423,6 +427,9 @@ public class Forge implements ApplicationListener { if (thickness > 1) { Gdx.gl.glLineWidth(thickness); } + if (alphaComposite < 1) { + color = FSkinColor.alphaColor(color, color.a * alphaComposite); + } if (color.a < 1 || cornerRadius > 0) { //enable blending so alpha colored shapes work properly Gdx.gl.glEnable(GL20.GL_BLEND); } @@ -471,6 +478,9 @@ public class Forge implements ApplicationListener { if (thickness > 1) { Gdx.gl.glLineWidth(thickness); } + if (alphaComposite < 1) { + color = FSkinColor.alphaColor(color, color.a * alphaComposite); + } Gdx.gl.glEnable(GL20.GL_BLEND); Gdx.gl.glEnable(GL10.GL_LINE_SMOOTH); //must be smooth to ensure edges aren't missed @@ -494,6 +504,9 @@ public class Forge implements ApplicationListener { public void fillRect(Color color, float x, float y, float w, float h) { batch.end(); //must pause batch while rendering shapes + if (alphaComposite < 1) { + color = FSkinColor.alphaColor(color, color.a * alphaComposite); + } if (color.a < 1) { //enable blending so alpha colored shapes work properly Gdx.gl.glEnable(GL20.GL_BLEND); } @@ -519,6 +532,9 @@ public class Forge implements ApplicationListener { if (thickness > 1) { Gdx.gl.glLineWidth(thickness); } + if (alphaComposite < 1) { + color = FSkinColor.alphaColor(color, color.a * alphaComposite); + } Gdx.gl.glEnable(GL20.GL_BLEND); Gdx.gl.glEnable(GL10.GL_LINE_SMOOTH); @@ -542,6 +558,9 @@ public class Forge implements ApplicationListener { public void fillCircle(Color color, float x, float y, float radius) { batch.end(); //must pause batch while rendering shapes + if (alphaComposite < 1) { + color = FSkinColor.alphaColor(color, color.a * alphaComposite); + } if (color.a < 1) { //enable blending so alpha colored shapes work properly Gdx.gl.glEnable(GL20.GL_BLEND); } @@ -564,6 +583,9 @@ public class Forge implements ApplicationListener { public void fillTriangle(Color color, float x1, float y1, float x2, float y2, float x3, float y3) { batch.end(); //must pause batch while rendering shapes + if (alphaComposite < 1) { + color = FSkinColor.alphaColor(color, color.a * alphaComposite); + } if (color.a < 1) { //enable blending so alpha colored shapes work properly Gdx.gl.glEnable(GL20.GL_BLEND); } @@ -592,6 +614,10 @@ public class Forge implements ApplicationListener { public void fillGradientRect(Color color1, Color color2, boolean vertical, float x, float y, float w, float h) { batch.end(); //must pause batch while rendering shapes + if (alphaComposite < 1) { + color1 = FSkinColor.alphaColor(color1, color1.a * alphaComposite); + color2 = FSkinColor.alphaColor(color2, color2.a * alphaComposite); + } boolean needBlending = (color1.a < 1 || color2.a < 1); if (needBlending) { //enable blending so alpha colored shapes work properly Gdx.gl.glEnable(GL20.GL_BLEND); @@ -613,10 +639,12 @@ public class Forge implements ApplicationListener { batch.begin(); } - public void setImageTint(Color color) { - batch.setColor(color); + public void setAlphaComposite(float alphaComposite0) { + alphaComposite = alphaComposite0; + batch.setColor(new Color(1, 1, 1, alphaComposite)); } - public void clearImageTint() { + public void resetAlphaComposite() { + alphaComposite = 1; batch.setColor(Color.WHITE); } @@ -651,6 +679,13 @@ public class Forge implements ApplicationListener { drawText(text, skinFont, skinColor.getColor(), x, y, w, h, wrap, horzAlignment, centerVertically); } public void drawText(String text, FSkinFont skinFont, Color color, float x, float y, float w, float h, boolean wrap, HAlignment horzAlignment, boolean centerVertically) { + if (alphaComposite < 1) { + color = FSkinColor.alphaColor(color, color.a * alphaComposite); + } + if (color.a < 1) { //enable blending so alpha colored shapes work properly + Gdx.gl.glEnable(GL20.GL_BLEND); + } + int fontSize = skinFont.getSize(); BitmapFont font = skinFont.getFont(); if (wrap) { @@ -679,6 +714,10 @@ public class Forge implements ApplicationListener { font.setColor(color); font.drawMultiLine(batch, text, adjustX(x), adjustY(y, 0), w, horzAlignment); } + + if (color.a < 1) { + Gdx.gl.glDisable(GL20.GL_BLEND); + } } private float adjustX(float x) { diff --git a/forge-m-base/src/forge/screens/constructed/ConstructedScreen.java b/forge-m-base/src/forge/screens/constructed/ConstructedScreen.java index 85d8173d822..fd61c62deb2 100644 --- a/forge-m-base/src/forge/screens/constructed/ConstructedScreen.java +++ b/forge-m-base/src/forge/screens/constructed/ConstructedScreen.java @@ -13,8 +13,10 @@ import java.util.Vector; import org.apache.commons.lang3.StringUtils; +import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment; import com.google.common.base.Predicate; +import forge.Forge.Graphics; import forge.assets.FSkin; import forge.assets.FSkinColor; import forge.assets.FSkinColor.Colors; @@ -49,7 +51,7 @@ import forge.utils.Utils; public class ConstructedScreen extends LaunchScreen { private static final FSkinColor PLAYER_BORDER_COLOR = FSkinColor.get(Colors.CLR_THEME).alphaColor(0.8f); private static final ForgePreferences prefs = FModel.getPreferences(); - + private static final float PADDING = 5; private static final int MAX_PLAYERS = 8; // General variables @@ -73,7 +75,13 @@ public class ConstructedScreen extends LaunchScreen { private final FScrollPane playersScroll = new FScrollPane() { @Override protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - //TODO + float y = 0; + float height; + for (int i = 0; i < activePlayersNum; i++) { + height = playerPanels.get(i).getPreferredHeight(); + playerPanels.get(i).setBounds(0, y, visibleWidth, height); + y += height; + } return new ScrollBounds(visibleWidth, visibleHeight); } }; @@ -122,9 +130,8 @@ public class ConstructedScreen extends LaunchScreen { ///////////////////// Player Panel ///////////////////// // Construct individual player panels - String constraints = "pushx, growx, wrap, hidemode 3"; for (int i = 0; i < MAX_PLAYERS; i++) { - teams.add(i+1); + teams.add(i + 1); archenemyTeams.add(i == 0 ? 1 : 2); PlayerPanel player = new PlayerPanel(i); @@ -134,12 +141,8 @@ public class ConstructedScreen extends LaunchScreen { player.setVisible(i < activePlayersNum); playersScroll.add(player); - - if (i == 0) { - constraints += ", gaptop 5px"; - } } - + add(playersScroll); addPlayerBtn.setCommand(new FEventHandler() { @@ -150,6 +153,11 @@ public class ConstructedScreen extends LaunchScreen { }); add(addPlayerBtn); } + + @Override + protected void doLayoutAboveBtnStart(float startY, float width, float height) { + playersScroll.setBounds(0, startY, width, height - startY); + } private void addPlayer() { if (activePlayersNum >= MAX_PLAYERS) { @@ -177,19 +185,6 @@ public class ConstructedScreen extends LaunchScreen { PlayerPanel player = playerPanels.get(playerIndex); player.setVisible(false); addPlayerBtn.setEnabled(true); - - //find closest player still in game and give focus - int min = MAX_PLAYERS; - int closest = 2; - - for (int participantIndex : getParticipants()) { - final int diff = Math.abs(playerIndex - participantIndex); - - if (diff < min) { - min = diff; - closest = participantIndex; - } - } } public boolean isPlayerAI(int playernum) { @@ -210,10 +205,6 @@ public class ConstructedScreen extends LaunchScreen { return participants; } - @Override - protected void doLayoutAboveBtnStart(float startY, float width, float height) { - } - @Override protected boolean buildLaunchParams(LaunchParams launchParams) { launchParams.gameType = GameType.Constructed; @@ -325,6 +316,61 @@ public class ConstructedScreen extends LaunchScreen { updateVariantControlsVisibility(); } + @Override + protected void doLayout(float width, float height) { + float x = PADDING; + float y = PADDING; + float fieldHeight = txtPlayerName.getHeight(); + float avatarSize = 2 * fieldHeight + PADDING; + + avatarLabel.setBounds(x, y, avatarSize, avatarSize); + x += avatarSize + PADDING; + float w = width - x - fieldHeight - 2 * PADDING; + txtPlayerName.setBounds(x, y, w, fieldHeight); + x += w + PADDING; + nameRandomiser.setBounds(x, y, fieldHeight, fieldHeight); + + y += fieldHeight + PADDING; + radioHuman.setHeight(fieldHeight); //must set height before width so icon is correct size + radioAi.setHeight(fieldHeight); + radioHuman.setWidth(radioHuman.getAutoSizeBounds().width); + radioAi.setWidth(radioAi.getAutoSizeBounds().width); + x = width - radioAi.getWidth(); + radioAi.setPosition(x, y); + x -= radioHuman.getWidth() - PADDING; + radioHuman.setPosition(x, y); + w = x - avatarSize - 2 * PADDING; + x = avatarSize + 2 * PADDING; + teamComboBox.setBounds(x, y, w, fieldHeight); + + y += fieldHeight + PADDING; + x = PADDING; + deckLabel.setBounds(x, y, avatarSize, fieldHeight); + x += avatarSize + PADDING; + w = width - x - PADDING; + deckBtn.setBounds(x, y, w, fieldHeight); + } + + private float getPreferredHeight() { + int rows = 3; + if (vntArchenemy.isSelected()) { + rows++; + } + if (vntPlanechase.isSelected()) { + rows++; + } + if (vntVanguard.isSelected()) { + rows++; + } + return rows * (txtPlayerName.getHeight() + PADDING) + PADDING; + } + + @Override + protected void drawOverlay(Graphics g) { + float y = getHeight(); + g.drawLine(1, PLAYER_BORDER_COLOR, 0, y, getWidth(), y); + } + private final FEventHandler radioMouseAdapter = new FEventHandler() { @Override public void handleEvent(FEvent e) { @@ -350,12 +396,6 @@ public class ConstructedScreen extends LaunchScreen { } }; - @Override - protected void doLayout(float width, float height) { - // TODO Auto-generated method stub - - } - private FEventHandler avatarCommand = new FEventHandler() { @Override public void handleEvent(FEvent e) { @@ -430,7 +470,7 @@ public class ConstructedScreen extends LaunchScreen { aeTeamComboBox.setEnabled(playerIsArchenemy); for (int i = 1; i <= MAX_PLAYERS; i++) { - teamComboBox.addItem(i); + teamComboBox.addItem("Team " + i); } teamComboBox.setSelectedIndex(teams.get(index) - 1); teamComboBox.setEnabled(true); @@ -691,7 +731,7 @@ public class ConstructedScreen extends LaunchScreen { /** Adds a pre-styled FLabel component with the specified title. */ private FLabel newLabel(String title) { - return new FLabel.Builder().text(title).fontSize(14).build(); + return new FLabel.Builder().text(title).fontSize(14).align(HAlignment.RIGHT).build(); } private List getUsedAvatars() { diff --git a/forge-m-base/src/forge/screens/match/views/VStack.java b/forge-m-base/src/forge/screens/match/views/VStack.java index a0e577da2e4..47733eab410 100644 --- a/forge-m-base/src/forge/screens/match/views/VStack.java +++ b/forge-m-base/src/forge/screens/match/views/VStack.java @@ -24,7 +24,7 @@ public class VStack extends FDropDown { private static final float CARD_WIDTH = Utils.AVG_FINGER_WIDTH; private static final float CARD_HEIGHT = Math.round(CARD_WIDTH * FCardPanel.ASPECT_RATIO); private static final FSkinFont FONT = FSkinFont.get(11); - private static final Color ALPHA_COMPOSITE = new Color(1, 1, 1, 0.5f); + private static final float ALPHA_COMPOSITE = 0.5f; private final MagicStack stack; private final LobbyPlayer localPlayer; @@ -104,7 +104,7 @@ public class VStack extends FDropDown { private class StackInstanceDisplay extends FDisplayObject { private final SpellAbilityStackInstance stackInstance; private final boolean isTop; - private FSkinColor foreColor, backColor; + private final FSkinColor foreColor, backColor; private String text; private StackInstanceDisplay(SpellAbilityStackInstance stackInstance0, boolean isTop0) { @@ -154,11 +154,6 @@ public class VStack extends FDropDown { backColor = FSkinColor.get(Colors.CLR_OVERLAY); foreColor = FSkinColor.get(Colors.CLR_TEXT); } - - if (!isTop) { - backColor = backColor.alphaColor(ALPHA_COMPOSITE.a); - foreColor = foreColor.alphaColor(ALPHA_COMPOSITE.a); - } } private float getMinHeight(float width) { @@ -174,6 +169,10 @@ public class VStack extends FDropDown { float w = getWidth(); float h = getHeight(); + if (!isTop) { + g.setAlphaComposite(ALPHA_COMPOSITE); + } + g.fillRect(backColor, 0, 0, w, h); float padding = PADDING; @@ -182,16 +181,14 @@ public class VStack extends FDropDown { float x = padding; float y = padding; - if (!isTop) { - g.setImageTint(ALPHA_COMPOSITE); - } g.drawImage(ImageCache.getImage(stackInstance.getSourceCard()), x, y, cardWidth, cardHeight); - if (!isTop) { - g.clearImageTint(); - } x += cardWidth + padding; g.drawText(text, FONT, foreColor, x, y, w - x - padding, h - y - padding, true, HAlignment.LEFT, true); + + if (!isTop) { + g.resetAlphaComposite(); + } } } } diff --git a/forge-m-base/src/forge/toolbox/FButton.java b/forge-m-base/src/forge/toolbox/FButton.java index 9cc50f92cbf..244ade3b23f 100644 --- a/forge-m-base/src/forge/toolbox/FButton.java +++ b/forge-m-base/src/forge/toolbox/FButton.java @@ -2,7 +2,6 @@ package forge.toolbox; import org.apache.commons.lang3.StringUtils; -import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment; import forge.Forge.Graphics; @@ -15,8 +14,7 @@ import forge.toolbox.FEvent.FEventType; public class FButton extends FDisplayObject { private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final Color DISABLED_COMPOSITE = new Color(1, 1, 1, 0.25f); - private static final FSkinColor DISABLED_FORE_COLOR = FORE_COLOR.alphaColor(DISABLED_COMPOSITE.a); + private static final float DISABLED_COMPOSITE = 0.25f; private FSkinImage imgL, imgM, imgR; private String text; @@ -155,11 +153,9 @@ public class FButton extends FDisplayObject { float cornerTextOffsetX = cornerButtonWidth / 2; float cornerTextOffsetY = (cornerButtonHeight - h) / 2; - FSkinColor foreColor = FORE_COLOR; boolean disabled = !isEnabled(); if (disabled) { - g.setImageTint(DISABLED_COMPOSITE); - foreColor = DISABLED_FORE_COLOR; + g.setAlphaComposite(DISABLED_COMPOSITE); } //determine images to draw and text alignment based on which corner button is in (if any) @@ -192,12 +188,12 @@ public class FButton extends FDisplayObject { break; } - if (disabled) { - g.clearImageTint(); + if (!StringUtils.isEmpty(text)) { + g.drawText(text, font, FORE_COLOR, x, y, w, h, false, HAlignment.CENTER, true); } - if (!StringUtils.isEmpty(text)) { - g.drawText(text, font, foreColor, x, y, w, h, false, HAlignment.CENTER, true); + if (disabled) { + g.resetAlphaComposite(); } } } diff --git a/forge-m-base/src/forge/toolbox/FCheckBox.java b/forge-m-base/src/forge/toolbox/FCheckBox.java index bdd256f92b2..47f255a6658 100644 --- a/forge-m-base/src/forge/toolbox/FCheckBox.java +++ b/forge-m-base/src/forge/toolbox/FCheckBox.java @@ -18,7 +18,7 @@ public class FCheckBox extends FLabel { this(text0, false); } public FCheckBox(String text0, boolean selected0) { - super(new Builder().align(HAlignment.LEFT).selectable().selected(selected0)); + super(new Builder().text(text0).align(HAlignment.LEFT).selectable().selected(selected0)); setIcon(new CheckBoxIcon()); } @@ -47,4 +47,9 @@ public class FCheckBox extends FLabel { } } } + + @Override + public void draw(Graphics g) { + drawContent(g, getWidth(), getHeight(), false); + } } diff --git a/forge-m-base/src/forge/toolbox/FLabel.java b/forge-m-base/src/forge/toolbox/FLabel.java index a8b551faf3e..7605a45e60e 100644 --- a/forge-m-base/src/forge/toolbox/FLabel.java +++ b/forge-m-base/src/forge/toolbox/FLabel.java @@ -17,6 +17,7 @@ public class FLabel extends FDisplayObject { //========== Default values for FLabel are set here. private float bldIconScaleFactor = 0.8f; private int bldFontSize = 14; + private float bldAlphaComposite = 0.7f; private HAlignment bldAlignment = HAlignment.LEFT; private Vector2 bldInsets = new Vector2(3, 3); @@ -48,6 +49,7 @@ public class FLabel extends FDisplayObject { public Builder selected() { selected(true); return this; } public Builder command(final FEventHandler c0) { this.bldCommand = c0; return this; } public Builder fontSize(final int i0) { this.bldFontSize = i0; return this; } + public Builder alphaComposite(final float a0) { this.bldAlphaComposite = a0; return this; } public Builder enabled(final boolean b0) { this.bldEnabled = b0; return this; } public Builder iconScaleAuto(final boolean b0) { this.bldIconScaleAuto = b0; return this; } public Builder iconScaleFactor(final float f0) { this.bldIconScaleFactor = f0; return this; } @@ -75,6 +77,7 @@ public class FLabel extends FDisplayObject { private float iconScaleFactor; private FSkinFont font; + private float alphaComposite; private HAlignment alignment; private Vector2 insets; private boolean selectable, selected, opaque, iconInBackground, iconScaleAuto, pressed; @@ -88,6 +91,7 @@ public class FLabel extends FDisplayObject { protected FLabel(final Builder b0) { iconScaleFactor = b0.bldIconScaleFactor; font = FSkinFont.get(b0.bldFontSize); + alphaComposite = b0.bldAlphaComposite; alignment = b0.bldAlignment; insets = b0.bldInsets; selectable = b0.bldSelectable; @@ -184,7 +188,7 @@ public class FLabel extends FDisplayObject { bounds.height += 2 * insets.y; if (icon != null) { - bounds.width += icon.getWidth(); + bounds.width += icon.getWidth() + insets.x; } return bounds; @@ -196,6 +200,11 @@ public class FLabel extends FDisplayObject { float h = getHeight(); g.startClip(0, 0, w, h); //start clip to ensure nothing escapes bounds + + boolean applyAlphaComposite = (opaque && !pressed); + if (applyAlphaComposite) { + g.setAlphaComposite(alphaComposite); + } if (pressed) { if (pressedColor != null) { @@ -220,6 +229,10 @@ public class FLabel extends FDisplayObject { drawContent(g, w, h, pressed); + if (applyAlphaComposite) { + g.resetAlphaComposite(); + } + g.endClip(); } @@ -249,14 +262,19 @@ public class FLabel extends FDisplayObject { y += (h - iconHeight) / 2; } else { - x = 0; //TODO: calculation these - y = 0; + //TODO: Calculate these for center/right alignment + y += (h - iconHeight) / 2; } g.drawImage(icon, x, y, iconWidth, iconHeight); if (!text.isEmpty()) { - x += iconWidth; + y = insets.y; + if (pressed) { + y++; + } + x += iconWidth + insets.x; + w -= iconWidth + insets.x; g.startClip(x, y, w, h); g.drawText(text, font, textColor, x, y, w, h, false, HAlignment.LEFT, true); g.endClip(); diff --git a/forge-m-base/src/forge/toolbox/FRadioButton.java b/forge-m-base/src/forge/toolbox/FRadioButton.java index f135e7a7051..d566ca43ea1 100644 --- a/forge-m-base/src/forge/toolbox/FRadioButton.java +++ b/forge-m-base/src/forge/toolbox/FRadioButton.java @@ -23,7 +23,7 @@ public class FRadioButton extends FLabel { this(text0, false); } public FRadioButton(String text0, boolean selected0) { - super(new Builder().align(HAlignment.LEFT).selectable().selected(selected0)); + super(new Builder().text(text0).align(HAlignment.LEFT).selectable().selected(selected0)); setIcon(new RadioButtonIcon()); } @@ -67,9 +67,9 @@ public class FRadioButton extends FLabel { @Override public void draw(Graphics g, float x, float y, float w, float h) { - float radius = h / 5; - x += w - radius; - y = h / 2; + float radius = h / 3; + x += w / 2; + y += h / 2; g.drawCircle(1, OUTER_CIRCLE_COLOR, x, y, radius); if (isSelected()) { g.fillCircle(INNER_CIRCLE_COLOR, x, y, radius / 2); @@ -77,6 +77,11 @@ public class FRadioButton extends FLabel { } } + @Override + public void draw(Graphics g) { + drawContent(g, getWidth(), getHeight(), false); + } + public static class RadioButtonGroup { private final List buttons = new ArrayList(); } diff --git a/forge-m-base/src/forge/toolbox/FTextField.java b/forge-m-base/src/forge/toolbox/FTextField.java index bf900194607..f184d20859a 100644 --- a/forge-m-base/src/forge/toolbox/FTextField.java +++ b/forge-m-base/src/forge/toolbox/FTextField.java @@ -9,8 +9,9 @@ import forge.assets.FSkinColor.Colors; import forge.toolbox.FEvent.FEventHandler; public class FTextField extends FDisplayObject { - private static final float PADDING = 3; + private static final float PADDING = 5; private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); + private static final FSkinColor BACK_COLOR = FSkinColor.get(Colors.CLR_THEME2); private FEventHandler changedHandler; private String text; @@ -22,7 +23,7 @@ public class FTextField extends FDisplayObject { } public FTextField(String text0) { text = text0; - font = FSkinFont.get(14); + setFontSize(14); alignment = HAlignment.LEFT; } @@ -42,6 +43,7 @@ public class FTextField extends FDisplayObject { public void setFontSize(int fontSize0) { font = FSkinFont.get(fontSize0); + setHeight(font.getFont().getCapHeight() * 3); } public FEventHandler getChangedHandler() { @@ -59,6 +61,10 @@ public class FTextField extends FDisplayObject { @Override public void draw(Graphics g) { - g.drawText(text, font, FORE_COLOR, PADDING, 0, getWidth() - 2 * PADDING, getHeight(), false, alignment, true); + float w = getWidth(); + float h = getHeight(); + g.fillRect(BACK_COLOR, 0, 0, w, h); + g.drawText(text, font, FORE_COLOR, PADDING, 0, w - 2 * PADDING, h, false, alignment, true); + g.drawRect(1, FORE_COLOR, 1, 1, w - 2, h - 2); //allow smooth border to fully display within bounds } }