diff --git a/core/src/main/java/art/arcane/iris/studio/map/BiomePalettePlacement.java b/core/src/main/java/art/arcane/iris/studio/map/BiomePalettePlacement.java index 51b339b15..a6c03c5ae 100644 --- a/core/src/main/java/art/arcane/iris/studio/map/BiomePalettePlacement.java +++ b/core/src/main/java/art/arcane/iris/studio/map/BiomePalettePlacement.java @@ -50,14 +50,15 @@ abstract class BiomePalettePlacement { RNG postRandom = new RNG(engine.getSeedManager().getPost()); int seaLevel = seaLevel(engine.getDimension()); int index = palette.index(); - IrisBiomePaletteLayer layer = palette.layerIn(biome); return switch (palette.kind()) { - case LAYER -> new StackedLayer(layer, index, biome.getLayerHeightGenerators(terrainRandom, data), terrainRandom, data); - case SEA_LAYER -> new StackedLayer(layer, index, biome.getLayerSeaHeightGenerators(terrainRandom, data), terrainRandom, data); - case CAVE_CEILING_LAYER -> new StackedLayer(layer, index, biome.getCaveCeilingLayerHeightGenerators(carveRandom, data), - carveRandom, data); - case WALL -> new SingleBlocks(layer, data, carveRandom, seaLevel); - case SLAB -> new SingleBlocks(layer, data, postRandom, seaLevel); + case LAYER -> new StackedLayer(palette.layerIn(biome), index, biome.getLayerHeightGenerators(terrainRandom, data), + terrainRandom, data); + case SEA_LAYER -> new StackedLayer(palette.layerIn(biome), index, biome.getLayerSeaHeightGenerators(terrainRandom, data), + terrainRandom, data); + case CAVE_CEILING_LAYER -> new StackedLayer(palette.layerIn(biome), index, + biome.getCaveCeilingLayerHeightGenerators(carveRandom, data), carveRandom, data); + case WALL -> new SingleBlocks(palette.layerIn(biome), data, carveRandom, seaLevel); + case SLAB -> new SingleBlocks(palette.layerIn(biome), data, postRandom, seaLevel); case DECORATOR -> new Decorations(palette.decoratorIn(biome), engine.getSeedManager().getComponent(), seaLevel, data); }; } diff --git a/core/src/main/java/art/arcane/iris/studio/map/MapWindow.java b/core/src/main/java/art/arcane/iris/studio/map/MapWindow.java index 07463d9c8..41de980c4 100644 --- a/core/src/main/java/art/arcane/iris/studio/map/MapWindow.java +++ b/core/src/main/java/art/arcane/iris/studio/map/MapWindow.java @@ -260,14 +260,13 @@ public final class MapWindow implements MapCanvas.Listener { canvas.showView(view); canvas.setActive(true); showControls(mapControls); - inspectorSlot.removeAll(); if (view == MapView.REGIONS) { showRegionExplorer(previousView); } else if (view == MapView.BIOMES) { showBiomeExplorer(); } else { useSidebar(viewListScroll); - inspectorSlot.add(legendPanel, BorderLayout.CENTER); + useInspector(legendPanel); } showCard(MAP_CARD); canvas.requestFocusInWindow(); @@ -293,9 +292,9 @@ public final class MapWindow implements MapCanvas.Listener { // The region and biome views share how the map draws its picks, so their switches show the same choice. private void showPickInspector(PickInspectorPanel inspector) { inspector.selectDisplay(canvas.pickDisplay()); - pickInspectorSplit.setTopComponent(inspector); - pickInspectorSplit.setBottomComponent(legendPanel); - inspectorSlot.add(pickInspectorSplit, BorderLayout.CENTER); + pickInspectorSplit.setTopComponent(StudioTheme.matchTheme(inspector)); + pickInspectorSplit.setBottomComponent(StudioTheme.matchTheme(legendPanel)); + useInspector(pickInspectorSplit); } private void stylePickInspectorSplit() { @@ -316,8 +315,7 @@ public final class MapWindow implements MapCanvas.Listener { canvas.setActive(false); showControls(explorerControls); useSidebar(viewListAbove(paletteExplorer.paletteSidebar())); - inspectorSlot.removeAll(); - inspectorSlot.add(paletteExplorer.paletteInspector(), BorderLayout.CENTER); + useInspector(paletteExplorer.paletteInspector()); showCard(PALETTES_CARD); EventQueue.invokeLater(() -> viewList.select(currentView)); if (firstOpen) { @@ -331,8 +329,7 @@ public final class MapWindow implements MapCanvas.Listener { canvas.setActive(false); showControls(explorerControls); useSidebar(viewListAbove(explorer.browser())); - inspectorSlot.removeAll(); - inspectorSlot.add(explorer.overview(), BorderLayout.CENTER); + useInspector(explorer.overview()); showCard(view.name()); EventQueue.invokeLater(() -> viewList.select(currentView)); if (firstOpen) { @@ -352,8 +349,7 @@ public final class MapWindow implements MapCanvas.Listener { canvas.setActive(false); showControls(worldControls, explorerControls); useSidebar(viewListScroll); - inspectorSlot.removeAll(); - inspectorSlot.add(worldExplorer.legend(), BorderLayout.CENTER); + useInspector(worldExplorer.legend()); showCard(WORLD_CARD); worldExplorer.show(worldCenterX, worldCenterZ, firstOpen || mapMoved); } @@ -430,7 +426,7 @@ public final class MapWindow implements MapCanvas.Listener { private JSplitPane viewListAbove(JComponent explorerSidebar) { boolean firstUse = explorerSplit.getBottomComponent() == null; explorerSplit.setTopComponent(viewListScroll); - explorerSplit.setBottomComponent(explorerSidebar); + explorerSplit.setBottomComponent(StudioTheme.matchTheme(explorerSidebar)); if (firstUse) { EventQueue.invokeLater(this::fitViewListAboveExplorer); } @@ -549,7 +545,12 @@ public final class MapWindow implements MapCanvas.Listener { private void useSidebar(JComponent component) { sidebar.removeAll(); - sidebar.add(component, BorderLayout.CENTER); + sidebar.add(StudioTheme.matchTheme(component), BorderLayout.CENTER); + } + + private void useInspector(JComponent component) { + inspectorSlot.removeAll(); + inspectorSlot.add(StudioTheme.matchTheme(component), BorderLayout.CENTER); } private void showCard(String card) { diff --git a/core/src/main/java/art/arcane/iris/studio/map/StudioTheme.java b/core/src/main/java/art/arcane/iris/studio/map/StudioTheme.java index c61ad5995..add8f5e4e 100644 --- a/core/src/main/java/art/arcane/iris/studio/map/StudioTheme.java +++ b/core/src/main/java/art/arcane/iris/studio/map/StudioTheme.java @@ -26,6 +26,8 @@ import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.configuration.IrisSettings; import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; import java.awt.Color; @@ -64,6 +66,7 @@ final class StudioTheme { static final int OVERLAY_ARC = 10; private static final boolean DARK_WITHOUT_SYSTEM_PREFERENCE = true; + private static final String MATCHED_DARK_PROPERTY = "iris.studio.matchedDark"; private static final AtomicBoolean INSTALLED = new AtomicBoolean(); private static final ExecutorService SYSTEM_CHECK = Executors.newSingleThreadExecutor(runnable -> { Thread thread = new Thread(runnable, "Iris Theme Check"); @@ -188,6 +191,19 @@ final class StudioTheme { }; } + /** + * A theme switch only reaches components inside a window, so a panel swapped out at the time keeps the old theme until + * this brings it up to date. Call it when putting a panel back on screen. + */ + static T matchTheme(T component) { + if (Boolean.valueOf(dark).equals(component.getClientProperty(MATCHED_DARK_PROPERTY))) { + return component; + } + SwingUtilities.updateComponentTreeUI(component); + component.putClientProperty(MATCHED_DARK_PROPERTY, dark); + return component; + } + private static void switchTo(boolean nextDark) { if (nextDark == dark) { return;