diff --git a/.gitattributes b/.gitattributes index 8051a41d81f..aea67b32b14 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1011,6 +1011,7 @@ forge-gui-desktop/src/main/java/forge/toolbox/FTabbedPane.java -text forge-gui-desktop/src/main/java/forge/toolbox/FTextArea.java -text forge-gui-desktop/src/main/java/forge/toolbox/FTextEditor.java -text forge-gui-desktop/src/main/java/forge/toolbox/FTextField.java -text +forge-gui-desktop/src/main/java/forge/toolbox/FTextPane.java -text forge-gui-desktop/src/main/java/forge/toolbox/FUndoManager.java -text forge-gui-desktop/src/main/java/forge/toolbox/IDisposable.java -text forge-gui-desktop/src/main/java/forge/toolbox/JXButtonPanel.java -text diff --git a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java index 87b50fbb2d7..876cf26036d 100644 --- a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java +++ b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java @@ -71,6 +71,7 @@ import forge.sound.IAudioMusic; import forge.toolbox.FButton; import forge.toolbox.FOptionPane; import forge.toolbox.FSkin; +import forge.toolbox.FSkin.SkinImage; import forge.toolbox.MouseTriggerEvent; import forge.toolbox.special.PhaseLabel; import forge.util.BuildInfo; @@ -146,6 +147,11 @@ public class GuiDesktop implements IGuiBase { return new FSkin.UnskinnedIcon(image, opacity); } + @Override + public void showImageDialog(ISkinImage image, String message, String title) { + FOptionPane.showMessageDialog(message, title, (SkinImage)image); + } + @Override public int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption) { return FOptionPane.showOptionDialog(message, title, icon == null ? null : FSkin.getImage(icon), options, defaultOption); diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FOptionPane.java b/forge-gui-desktop/src/main/java/forge/toolbox/FOptionPane.java index b14cbbbad52..7d6b553f431 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FOptionPane.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FOptionPane.java @@ -5,6 +5,7 @@ import forge.toolbox.FSkin.SkinImage; import forge.view.FDialog; import javax.swing.*; +import javax.swing.text.StyleConstants; import java.awt.*; import java.awt.event.ActionEvent; @@ -137,21 +138,41 @@ public class FOptionPane extends FDialog { int padding = 10; int x = padding; int gapAboveButtons = padding * 3 / 2; - int gapBottom = comp == null ? gapAboveButtons: padding; + int gapBottom = comp == null ? gapAboveButtons : padding; + FLabel centeredLabel = null; + FTextPane centeredPrompt = null; if (icon != null) { - FLabel lblIcon = new FLabel.Builder().icon(icon).build(); - int labelWidth = icon.getWidth(); - this.add(lblIcon, "x " + (x - 3) + ", ay top, w " + labelWidth + ", h " + icon.getHeight() + ", gapbottom " + gapBottom); - x += labelWidth; + if (icon.getWidth() < 100) { + FLabel lblIcon = new FLabel.Builder().icon(icon).build(); + this.add(lblIcon, "x " + (x - 3) + ", ay top, w " + icon.getWidth() + ", h " + icon.getHeight() + ", gapbottom " + gapBottom); + x += icon.getWidth(); + } + else { + FLabel lblIcon = new FLabel.Builder().icon(icon).iconInBackground(true).iconScaleFactor(1).iconAlignX(SwingConstants.CENTER).build(); + lblIcon.setMinimumSize(new Dimension(icon.getWidth() * 2, icon.getHeight())); + this.add(lblIcon, "x " + x + ", ay top, wrap, gapbottom " + gapBottom); + centeredLabel = lblIcon; + } } if (message != null) { - FTextArea prompt = new FTextArea(message); - prompt.setFont(FSkin.getFont(14)); - prompt.setAutoSize(true); - Dimension parentSize = JOptionPane.getRootFrame().getSize(); - prompt.setMaximumSize(new Dimension(parentSize.width / 2, parentSize.height - 100)); - this.add(prompt, "x " + x + ", ay top, wrap, gaptop " + (icon == null ? 0 : 7) + ", gapbottom " + gapBottom); + if (centeredLabel == null) { + FTextArea prompt = new FTextArea(message); + prompt.setFont(FSkin.getFont(14)); + prompt.setAutoSize(true); + Dimension parentSize = JOptionPane.getRootFrame().getSize(); + prompt.setMaximumSize(new Dimension(parentSize.width / 2, parentSize.height - 100)); + this.add(prompt, "x " + x + ", ay top, wrap, gaptop " + (icon == null ? 0 : 7) + ", gapbottom " + gapBottom); + } + else { + FTextPane prompt = new FTextPane(message); + prompt.setFont(FSkin.getFont(14)); + prompt.setTextAlignment(StyleConstants.ALIGN_CENTER); + Dimension parentSize = JOptionPane.getRootFrame().getSize(); + prompt.setMaximumSize(new Dimension(parentSize.width / 2, parentSize.height - 100)); + this.add(prompt, "x " + x + ", ay top, wrap, gapbottom " + gapBottom); + centeredPrompt = prompt; + } x = padding; } if (comp != null) { @@ -233,6 +254,11 @@ public class FOptionPane extends FDialog { x += dx; } + if (centeredLabel != null) { + centeredLabel.setPreferredSize(new Dimension(width - 2 * padding, centeredLabel.getMinimumSize().height)); + centeredPrompt.setPreferredSize(new Dimension(width - 2 * padding, centeredPrompt.getPreferredSize().height)); + } + this.setSize(width, this.getHeight() + buttonHeight); //resize dialog again to account for buttons } diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FTextPane.java b/forge-gui-desktop/src/main/java/forge/toolbox/FTextPane.java new file mode 100644 index 00000000000..159733139cc --- /dev/null +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FTextPane.java @@ -0,0 +1,37 @@ +package forge.toolbox; + +import forge.toolbox.FSkin.SkinnedTextPane; + +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; + +/** + * A custom instance of JTextArea using Forge skin properties. + * + */ +@SuppressWarnings("serial") +public class FTextPane extends SkinnedTextPane { + /** */ + public FTextPane() { + super(); + this.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); + this.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT)); + this.setOpaque(false); + this.setFocusable(false); + this.setEditable(false); + } + /** @param str {@java.lang.String} */ + public FTextPane(final String str) { + this(); + this.setText(str); + } + + //Use constant in StyleConstants + public void setTextAlignment(int alignment) { + StyledDocument doc = getStyledDocument(); + SimpleAttributeSet attrSet = new SimpleAttributeSet(); + StyleConstants.setAlignment(attrSet, alignment); + doc.setParagraphAttributes(0, doc.getLength(), attrSet, false); + } +} diff --git a/forge-gui-mobile/src/forge/GuiMobile.java b/forge-gui-mobile/src/forge/GuiMobile.java index 756b991c017..796e6dcc2c6 100644 --- a/forge-gui-mobile/src/forge/GuiMobile.java +++ b/forge-gui-mobile/src/forge/GuiMobile.java @@ -15,6 +15,7 @@ import com.google.common.base.Function; import forge.assets.FBufferedImage; import forge.assets.FDelayLoadImage; +import forge.assets.FImage; import forge.assets.FSkin; import forge.assets.FSkinProp; import forge.assets.FTextureImage; @@ -127,6 +128,16 @@ public class GuiMobile implements IGuiBase { }; } + @Override + public void showImageDialog(final ISkinImage image, final String message, final String title) { + new WaitCallback() { + @Override + public void run() { + FOptionPane.showMessageDialog(message, title, (FImage)image); + } + }.invokeAndWait(); + } + @Override public int showOptionDialog(final String message, final String title, final FSkinProp icon, final String[] options, final int defaultOption) { return new WaitCallback() { diff --git a/forge-gui/src/main/java/forge/achievement/Achievement.java b/forge-gui/src/main/java/forge/achievement/Achievement.java index 665c5c7b0ac..248202db587 100644 --- a/forge-gui/src/main/java/forge/achievement/Achievement.java +++ b/forge-gui/src/main/java/forge/achievement/Achievement.java @@ -8,7 +8,6 @@ import forge.assets.ISkinImage; import forge.game.Game; import forge.game.player.Player; import forge.interfaces.IGuiBase; -import forge.util.gui.SOptionPane; public abstract class Achievement { private final String displayName, sharedDesc, commonDesc, uncommonDesc, rareDesc, mythicDesc; @@ -147,6 +146,7 @@ public abstract class Achievement { } else if (current >= best) { return; } + boolean hadEarnedSpecial = earnedSpecial(); boolean hadEarnedMythic = earnedMythic(); boolean hadEarnedRare = earnedRare(); boolean hadEarnedUncommon = earnedUncommon(); @@ -154,6 +154,16 @@ public abstract class Achievement { best = current; + if (earnedSpecial()) { + if (!hadEarnedSpecial) { + if (image != null) { //only update image if it has already been initialized + updateTrophyImage(); + } + gui.showImageDialog(image, displayName + "\n" + sharedDesc + ".", "Achievement Earned"); + } + return; + } + String type = null; String desc = null; if (earnedMythic()) { @@ -181,14 +191,11 @@ public abstract class Achievement { } } if (type != null) { - if (image != null) { //only update image if it has already been initialized - updateTrophyImage(); - } + updateTrophyImage(); if (sharedDesc != null) { desc = sharedDesc + " " + desc; } - SOptionPane.showMessageDialog(gui, "You've earned a " + type + " trophy!\n\n" + - displayName + "\n" + desc + ".", "Achievement Earned", overlayImage); + gui.showImageDialog(image, displayName + " (" + type + ")\n" + desc + ".", "Achievement Earned"); } } diff --git a/forge-gui/src/main/java/forge/achievement/VariantWins.java b/forge-gui/src/main/java/forge/achievement/VariantWins.java index f1d9d94cfa5..a9d760ffa33 100644 --- a/forge-gui/src/main/java/forge/achievement/VariantWins.java +++ b/forge-gui/src/main/java/forge/achievement/VariantWins.java @@ -4,16 +4,17 @@ import forge.assets.FSkinProp; import forge.game.Game; import forge.game.GameType; import forge.game.player.Player; +import forge.util.Lang; public class VariantWins extends Achievement { private GameType variant; public VariantWins(GameType variant0, int silver0, int gold0, int mythic0, FSkinProp image0) { super(variant0.toString(), null, - String.format("Win a %s game", variant0.toString()), 1, - String.format("Win %d %s games", silver0, variant0.toString()), silver0, - String.format("Win %d %s games", gold0, variant0.toString()), gold0, - String.format("Win %d %s games", mythic0, variant0.toString()), mythic0, + "Win " + Lang.nounWithAmount(1, variant0.toString() + " game"), 1, + "Win " + Lang.nounWithAmount(silver0, variant0.toString() + " game"), silver0, + "Win " + Lang.nounWithAmount(gold0, variant0.toString() + " game"), gold0, + "Win " + Lang.nounWithAmount(mythic0, variant0.toString() + " game"), mythic0, image0); variant = variant0; } diff --git a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java index ea64fae53b1..6c4f40f5b56 100644 --- a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java +++ b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java @@ -41,6 +41,7 @@ public interface IGuiBase { ISkinImage getUnskinnedIcon(String path); ISkinImage createLayeredImage(FSkinProp background, FSkinProp overlay, float opacity); void showBugReportDialog(String title, String text, boolean showExitAppBtn); + void showImageDialog(ISkinImage image, String message, String title); int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption); int showCardOptionDialog(CardView card, String message, String title, FSkinProp icon, String[] options, int defaultOption); T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions);