Keep the map legend readable

Long biome names now shorten instead of pushing the percentages out of
the legend, and biomes that share a display name show their key. The
highlight edge tints instead of drawing solid white, which turned
biomes scattered pixel by pixel into noise.

Model used: Claude Opus 5.5
This commit is contained in:
piexel committed 2026-10-19 12:51:58 +02:00
1 parent 340e66105c
commit ec0d2d816a
2 files changed
+31 -3

No files matched your search

@@ -37,8 +37,10 @@ import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.function.Consumer;
/**
@@ -56,7 +58,14 @@ final class MapLegendPanel extends JPanel {
private final JLabel title = new JLabel();
private final DefaultListModel<MapCensus.Share> rows = new DefaultListModel<>();
private final JList<MapCensus.Share> list = new JList<>(rows);
private final JList<MapCensus.Share> list = new JList<>(rows) {
// Long names shorten with an ellipsis instead of pushing the percentages out of sight.
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
};
private final Set<String> sharedNames = new HashSet<>();
private MapStyle.Highlight highlight;
MapLegendPanel(Consumer<MapCensus.Share> onRowClicked) {
@@ -97,6 +106,7 @@ final class MapLegendPanel extends JPanel {
void show(String subjectTitle, List<MapCensus.Share> shares, MapStyle.Highlight nextHighlight) {
title.setText(subjectTitle.toUpperCase(Locale.ROOT));
highlight = nextHighlight;
rememberSharedNames(shares);
if (!sameRows(shares)) {
rows.clear();
rows.addAll(shares);
@@ -104,6 +114,22 @@ final class MapLegendPanel extends JPanel {
list.repaint();
}
// Two biomes can share a display name; those rows show their key so they can be told apart.
private void rememberSharedNames(List<MapCensus.Share> shares) {
Set<String> seen = new HashSet<>();
sharedNames.clear();
for (MapCensus.Share share : shares) {
if (!seen.add(share.label().name())) {
sharedNames.add(share.label().name());
}
}
}
private String rowText(MapCensus.Share share) {
String name = share.label().name();
return sharedNames.contains(name) ? name + " (" + share.label().key() + ")" : name;
}
private boolean sameRows(List<MapCensus.Share> shares) {
if (rows.size() != shares.size()) {
return false;
@@ -157,7 +183,7 @@ final class MapLegendPanel extends JPanel {
@Override
public Component getListCellRendererComponent(JList<?> owner, Object value, int index, boolean selected, boolean focused) {
MapCensus.Share share = (MapCensus.Share) value;
super.getListCellRendererComponent(owner, share.label().name(), index, isHighlighted(share), false);
super.getListCellRendererComponent(owner, rowText(share), index, isHighlighted(share), false);
setFont(StudioTheme.font());
setBorder(StudioTheme.emptyBorder(0, ROW_PADDING + SWATCH_SIZE + SWATCH_GAP, 0, ROW_PADDING + PERCENT_WIDTH));
setToolTipText(share.label().key());
@@ -41,6 +41,8 @@ public final class MapTile {
private static final double DIM_AMOUNT = 0.72D;
private static final double DIM_DESATURATION = 0.6D;
private static final int HIGHLIGHT_EDGE = 0xFFFFFF;
// A solid outline turns biomes that are scattered pixel by pixel into white noise, so the edge only tints.
private static final double HIGHLIGHT_EDGE_STRENGTH = 0.55D;
private static final int REGION_BORDER = 0x101114;
private static final double REGION_BORDER_STRENGTH = 0.6D;
@@ -168,7 +170,7 @@ public final class MapTile {
|| grid[gridIndex(pixelX - 1, pixelZ)] != highlighted
|| grid[gridIndex(pixelX, pixelZ + 1)] != highlighted
|| grid[gridIndex(pixelX, pixelZ - 1)] != highlighted;
return edge ? HIGHLIGHT_EDGE : color;
return edge ? blend(color, HIGHLIGHT_EDGE, HIGHLIGHT_EDGE_STRENGTH) : color;
}
private boolean isRegionEdge(int pixelX, int pixelZ) {