diff --git a/docs/icon-scaling-preview.png b/docs/icon-scaling-preview.png new file mode 100644 index 00000000000..366113139c7 Binary files /dev/null and b/docs/icon-scaling-preview.png differ diff --git a/forge-gui-desktop/src/main/java/forge/gui/framework/DragCell.java b/forge-gui-desktop/src/main/java/forge/gui/framework/DragCell.java index 63aedf90e16..83201b94bdf 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/framework/DragCell.java +++ b/forge-gui-desktop/src/main/java/forge/gui/framework/DragCell.java @@ -39,6 +39,7 @@ public final class DragCell extends JPanel implements ILocalRepaint { private int smoothY = 0; private int smoothW = 0; private int smoothH = 0; + private int minW = SResizingUtil.W_MIN; // Core layout stuff private final JPanel pnlHead = new JPanel(new MigLayout("insets 0, gap 0, hidemode 3")); @@ -258,6 +259,14 @@ public void setSmoothW(final int w0) { this.smoothW = w0; } + public int getMinW() { + return minW; + } + + public void setMinW(final int minW0) { + this.minW = minW0; + } + /** @param h0   int */ public void setSmoothH(final int h0) { this.smoothH = h0; diff --git a/forge-gui-desktop/src/main/java/forge/gui/framework/SResizingUtil.java b/forge-gui-desktop/src/main/java/forge/gui/framework/SResizingUtil.java index 0575fea6ac9..3302a78f4d8 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/framework/SResizingUtil.java +++ b/forge-gui-desktop/src/main/java/forge/gui/framework/SResizingUtil.java @@ -208,11 +208,11 @@ public static void resizeX(final MouseEvent e) { boolean rightLock = false; for (final DragCell t : LEFT_PANELS) { - if ((t.getW() + dX) < W_MIN) { leftLock = true; break; } + if ((t.getW() + dX) < t.getMinW()) { leftLock = true; break; } } for (final DragCell t : RIGHT_PANELS) { - if ((t.getW() - dX) < W_MIN) { rightLock = true; break; } + if ((t.getW() - dX) < t.getMinW()) { rightLock = true; break; } } if (dX < 0 && leftLock) { return; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VField.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VField.java index b463b915aed..8adb0aa9655 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VField.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VField.java @@ -153,13 +153,14 @@ public void mouseExited(final MouseEvent e) { @Override public void populate() { + parentCell.setMinW(240); final JPanel pnl = parentCell.getBody(); pnl.setLayout(new MigLayout("insets 0, gap 0")); - pnl.add(avatarArea, "w 10%!, h 35%!"); - pnl.add(phaseIndicator, "w 5%!, h 100%!, span 1 2"); - pnl.add(scroller, "w 85%!, h 100%!, span 1 2, wrap"); - pnl.add(detailsPanel, "w 10%!, h 64%!, gapleft 1px"); + pnl.add(avatarArea, "w 90px!, h 35%!"); + pnl.add(phaseIndicator, "w 22px!, h 100%!, span 1 2"); + pnl.add(scroller, "w 0:100%, growx, h 100%!, span 1 2, wrap"); + pnl.add(detailsPanel, "w 90px!, h 64%!, gapleft 1px"); } @Override diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FLabel.java b/forge-gui-desktop/src/main/java/forge/toolbox/FLabel.java index 413d3fde747..b2d1f20a99e 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FLabel.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FLabel.java @@ -478,10 +478,15 @@ public Runnable getRightClickCommand() { return this.cmdRightClick; } + protected double getEffectiveIconScaleFactor() { + return iconScaleFactor; + } + protected int getMaxTextWidth() { final int w = getWidth(); final int h = getHeight(); - final int sh = (int) (h * iconScaleFactor); + final int basis = iconInBackground ? Math.min(h, w) : h; + final int sh = (int) (basis * getEffectiveIconScaleFactor()); final int sw = (int) (sh * iar); return w - sw; } @@ -590,7 +595,8 @@ protected void paintContent(final Graphics2D g, final int w, final int h, final // Icon in background if (iconInBackground) { - final int sh = (int) (h * iconScaleFactor); + final int basis = Math.min(h, w); + final int sh = (int) (basis * getEffectiveIconScaleFactor()); final int sw = (int) (sh * iar); final int x = iconAlignX == SwingConstants.CENTER @@ -655,9 +661,11 @@ private static void paintDown(final Graphics2D g, final int w, final int h) { } protected void resetIcon() { - // Non-background icon + // Non-background icon — scale based on the smaller of width/height + // so icons shrink when the panel gets narrow, not just short if (img != null && iconScaleAuto && !iconInBackground) { - final int h = (int) (getHeight() * iconScaleFactor); + final int basis = Math.min(getHeight(), getWidth()); + final int h = (int) (basis * iconScaleFactor); final int w = (int) (h * iar); if (w == 0 || h == 0) { return; } diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java b/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java index 4bbd16e7947..7f2057dcb35 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java @@ -185,11 +185,40 @@ public void onLeftClick(final MouseEvent e) { } private static abstract class DetailLabel extends FLabel { + private final int baseFontSize; + private final double baseIconScaleFactor; + public DetailLabel(final FSkinProp icon) { + this(icon, 14, 0.85); + } + + public DetailLabel(final FSkinProp icon, int fontSize, double iconScaleFactor) { super(new FLabel.Builder().icon(FSkin.getImage(icon)) - .opaque(false).fontSize(14).hoverable() + .opaque(false).fontSize(fontSize).hoverable() .fontStyle(Font.BOLD).iconInBackground() + .iconScaleFactor(iconScaleFactor) .fontAlign(SwingConstants.RIGHT)); + this.baseFontSize = fontSize; + this.baseIconScaleFactor = iconScaleFactor; + } + + @Override + protected double getEffectiveIconScaleFactor() { + final String text = getText(); + if (text == null || text.length() <= 1) { return baseIconScaleFactor; } + final int w = getWidth(); + if (w == 0) { return baseIconScaleFactor; } + final int basis = Math.min(getHeight(), w); + if (basis == 0) { return baseIconScaleFactor; } + // For 2+ digit numbers, shrink the icon aggressively so text has room. + // 2 digits: 0.55x, 3 digits: 0.40x, 4+: 0.30x + final double reduction; + switch (text.length()) { + case 2: reduction = 0.55; break; + case 3: reduction = 0.40; break; + default: reduction = 0.30; break; + } + return baseIconScaleFactor * reduction; } public abstract void onContentUpdate(); @@ -216,7 +245,7 @@ private void autoSizeFont() { final int max = getMaxTextWidth(); SkinFont font = null; - for (int fontSize = 14; fontSize > 5; fontSize--) { + for (int fontSize = baseFontSize; fontSize > 5; fontSize--) { font = FSkin.getBoldFont(fontSize); if (font.measureTextWidth(g, text) <= max) { break; @@ -237,7 +266,13 @@ public DetailLabelNumeric(final FSkinProp icon, final String tooltipLabel, public DetailLabelNumeric(final FSkinProp icon, final String tooltipLabel, Function countFunction, Function toolTipExtraArg) { - super(icon); + this(icon, tooltipLabel, countFunction, toolTipExtraArg, 14, 0.85); + } + + public DetailLabelNumeric(final FSkinProp icon, final String tooltipLabel, + Function countFunction, Function toolTipExtraArg, + int fontSize, double iconScaleFactor) { + super(icon, fontSize, iconScaleFactor); this.countFunction = countFunction; //Format in one or two format args depending on if we have a second parameter. @@ -274,7 +309,8 @@ private class DetailLabelMana extends DetailLabelNumeric { public final String color; public DetailLabelMana(String color, String toolTipLabel) { - super(FSkinProp.MANA_IMG.get(color), toolTipLabel, (PlayerView p) -> p.getMana(ManaAtom.fromName(color))); + super(FSkinProp.MANA_IMG.get(color), toolTipLabel, + (PlayerView p) -> p.getMana(ManaAtom.fromName(color)), null, 16, 0.70); this.color = color; } }