diff --git a/src/main/java/appeng/client/gui/me/common/MEStorageScreen.java b/src/main/java/appeng/client/gui/me/common/MEStorageScreen.java index 3477f1a4efc..287b1453721 100644 --- a/src/main/java/appeng/client/gui/me/common/MEStorageScreen.java +++ b/src/main/java/appeng/client/gui/me/common/MEStorageScreen.java @@ -301,7 +301,7 @@ private boolean shouldCraftOnClick(GridInventoryEntry entry) { } private void updateScrollbar() { - scrollbar.setHeight(this.rows * style.getRow().getSrcHeight() - 2); + scrollbar.setHeight(this.rows * style.getRow().getSrcHeight()); int totalRows = (this.repo.size() + getSlotsPerRow() - 1) / getSlotsPerRow(); if (repo.hasPinnedRow()) { totalRows++; diff --git a/src/main/java/appeng/client/gui/me/items/ProcessingEncodingPanel.java b/src/main/java/appeng/client/gui/me/items/ProcessingEncodingPanel.java index c38eccecda6..eb7295b8794 100644 --- a/src/main/java/appeng/client/gui/me/items/ProcessingEncodingPanel.java +++ b/src/main/java/appeng/client/gui/me/items/ProcessingEncodingPanel.java @@ -36,7 +36,7 @@ public ProcessingEncodingPanel(PatternEncodingTermScreen> screen, WidgetContai this.cycleOutputBtn.setHalfSize(true); widgets.add("processingCycleOutput", this.cycleOutputBtn); - this.scrollbar = widgets.addScrollBar("processingPatternModeScrollbar", Scrollbar.SMALL); + this.scrollbar = widgets.addScrollBar("processingPatternModeScrollbar"); // The scrollbar ranges from 0 to the number of rows not visible this.scrollbar.setRange(0, menu.getProcessingInputSlots().length / 3 - 3, 3); this.scrollbar.setCaptureMouseWheel(false); diff --git a/src/main/java/appeng/client/gui/me/items/StonecuttingEncodingPanel.java b/src/main/java/appeng/client/gui/me/items/StonecuttingEncodingPanel.java index 3c3fb4896ea..14e97f3d8f7 100644 --- a/src/main/java/appeng/client/gui/me/items/StonecuttingEncodingPanel.java +++ b/src/main/java/appeng/client/gui/me/items/StonecuttingEncodingPanel.java @@ -46,7 +46,7 @@ public final class StonecuttingEncodingPanel extends EncodingModePanel { public StonecuttingEncodingPanel(PatternEncodingTermScreen> screen, WidgetContainer widgets) { super(screen, widgets); - this.scrollbar = widgets.addScrollBar("stonecuttingPatternModeScrollbar", Scrollbar.SMALL); + this.scrollbar = widgets.addScrollBar("stonecuttingPatternModeScrollbar"); this.scrollbar.setRange(0, 0, COLS); this.scrollbar.setCaptureMouseWheel(false); } diff --git a/src/main/java/appeng/client/gui/me/patternaccess/PatternAccessTermScreen.java b/src/main/java/appeng/client/gui/me/patternaccess/PatternAccessTermScreen.java index 0a43d798a65..559be4bd6fc 100644 --- a/src/main/java/appeng/client/gui/me/patternaccess/PatternAccessTermScreen.java +++ b/src/main/java/appeng/client/gui/me/patternaccess/PatternAccessTermScreen.java @@ -534,7 +534,7 @@ private void refreshList() { */ private void resetScrollbar() { // Needs to take the border into account, so offset for 1 px on the top and bottom. - scrollbar.setHeight(this.visibleRows * ROW_HEIGHT - 2); + scrollbar.setHeight(this.visibleRows * ROW_HEIGHT); scrollbar.setRange(0, this.rows.size() - this.visibleRows, 2); } diff --git a/src/main/java/appeng/client/gui/widgets/Scrollbar.java b/src/main/java/appeng/client/gui/widgets/Scrollbar.java index de7f39eb0e2..f927285639e 100644 --- a/src/main/java/appeng/client/gui/widgets/Scrollbar.java +++ b/src/main/java/appeng/client/gui/widgets/Scrollbar.java @@ -24,13 +24,14 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.navigation.ScreenRectangle; import net.minecraft.client.renderer.Rect2i; +import net.minecraft.client.resources.metadata.gui.GuiSpriteScaling; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import appeng.client.Point; import appeng.client.gui.ICompositeWidget; -import appeng.client.gui.style.Blitter; import appeng.core.AppEng; /** @@ -38,29 +39,26 @@ *
* It is expected that the background of the UI contains a pre-baked scrollbar track border, and that the exact * rectangle of that track is set on this object via {@link #displayX}, {@link #displayY} and {@link #setHeight(int)}. - * While the width of the track can also be set, the drawn handle will use vanilla's sprite width (see - * {@link Style#handleWidth()}. */ public class Scrollbar implements IScrollSource, ICompositeWidget { private boolean visible = true; /** - * The screen x-coordinate of the scrollbar's inner track. + * The screen x-coordinate of the scrollbar. */ private int displayX = 0; /** - * The screen y-coordinate of the scrollbar's inner track. + * The screen y-coordinate of the scrollbar. */ private int displayY = 0; private final Style style; - /** - * The inner height of the scrollbar track. - */ - private int height = 16; + private int width = 14; + private int height = 18; + private int pageSize = 1; private int maxScroll = 0; @@ -94,7 +92,7 @@ public Scrollbar() { @Override public Rect2i getBounds() { - return new Rect2i(displayX, displayY, style.handleWidth(), height); + return new Rect2i(displayX, displayY, width, height); } /** @@ -108,17 +106,27 @@ public void drawForegroundLayer(GuiGraphics guiGraphics, Rect2i bounds, Point mo // guiGraphics.fill( displayX, displayY, this.displayX + width, this.displayY + // height, 0xffff0000); + guiGraphics.blitSprite(style.trackSprite(), displayX, displayY, width, height); + + // Blit the handle + var innerTrack = getInnerTrackRect(); + int yOffset; - Blitter image; + ResourceLocation image; if (this.getRange() == 0) { yOffset = 0; - image = Blitter.guiSprite(style.disabledSprite()); + image = style.disabledSprite(); } else { yOffset = getHandleYOffset(); - image = Blitter.guiSprite(style.enabledSprite()); + image = style.enabledSprite(); } - image.dest(this.displayX, this.displayY + yOffset).blit(guiGraphics); + guiGraphics.blitSprite( + image, + displayX + innerTrack.left(), + displayY + innerTrack.top() + yOffset, + innerTrack.width(), + style.handleHeight()); } /** @@ -128,7 +136,7 @@ private int getHandleYOffset() { if (getRange() == 0) { return 0; } - int availableHeight = this.height - style.handleHeight(); + int availableHeight = getInnerTrackRect().height() - style.handleHeight(); return (this.currentScroll - this.minScroll) * availableHeight / this.getRange(); } @@ -152,6 +160,9 @@ public void setSize(int width, int height) { if (height != 0) { this.height = height; } + if (width != 0) { + this.width = width; + } } public void setRange(int min, int max, int pageSize) { @@ -241,7 +252,7 @@ public boolean onMouseDrag(Point mousePos, int button) { // the upper edge of it) within the scrollable area of the track (minus the // handle height). double handleUpperEdgeY = mousePos.getY() - this.displayY - this.dragYOffset; - double availableHeight = this.height - style.handleHeight(); + double availableHeight = getInnerTrackRect().height() - style.handleHeight(); double position = Mth.clamp(handleUpperEdgeY / availableHeight, 0.0, 1.0); this.currentScroll = this.minScroll + (int) Math.round(position * this.getRange()); @@ -285,6 +296,21 @@ public void tick() { this.eventRepeater.tick(); } + private ScreenRectangle getInnerTrackRect() { + var minecraft = Minecraft.getInstance(); + var resolvedTrackSprite = minecraft.getGuiSprites().getSprite(style.trackSprite()); + var scaling = minecraft.getGuiSprites().getSpriteScaling(resolvedTrackSprite); + if (scaling instanceof GuiSpriteScaling.NineSlice nineSlice) { + return new ScreenRectangle( + nineSlice.border().left(), + nineSlice.border().top(), + width - nineSlice.border().left() - nineSlice.border().right(), + height - nineSlice.border().top() - nineSlice.border().bottom()); + } else { + return new ScreenRectangle(0, 0, width, height); + } + } + private void pageUp() { this.currentScroll -= this.pageSize; this.applyRange(); @@ -296,30 +322,22 @@ private void pageDown() { } public static final Style DEFAULT = Style.create( - new ResourceLocation("minecraft", "container/creative_inventory/scroller"), - new ResourceLocation("minecraft", "container/creative_inventory/scroller_disabled")); - - public static final Style SMALL = Style.create( - AppEng.makeId("small_scroller"), - AppEng.makeId("small_scroller_disabled")); + AppEng.makeId("sunken_panel_dark"), + AppEng.makeId("scroll_handle"), + AppEng.makeId("scroll_handle_disabled"), + 15); public record Style( + ResourceLocation trackSprite, ResourceLocation enabledSprite, - ResourceLocation disabledSprite) { + ResourceLocation disabledSprite, + int handleHeight) { public static Style create( + ResourceLocation trackSprite, ResourceLocation enabledSprite, - ResourceLocation disabledSprite) { - return new Style(enabledSprite, disabledSprite); - } - - public int handleWidth() { - var minecraft = Minecraft.getInstance(); - return minecraft.getGuiSprites().getSprite(enabledSprite).contents().width(); - } - - public int handleHeight() { - var minecraft = Minecraft.getInstance(); - return minecraft.getGuiSprites().getSprite(enabledSprite).contents().height(); + ResourceLocation disabledSprite, + int handleHeight) { + return new Style(trackSprite, enabledSprite, disabledSprite, handleHeight); } } diff --git a/src/main/resources/assets/ae2/screens/craft_confirm.json b/src/main/resources/assets/ae2/screens/craft_confirm.json index 11bc965b218..16031c3d14d 100644 --- a/src/main/resources/assets/ae2/screens/craft_confirm.json +++ b/src/main/resources/assets/ae2/screens/craft_confirm.json @@ -22,9 +22,10 @@ }, "widgets": { "scrollbar": { - "left": 218, - "top": 19, - "height": 114 + "left": 217, + "top": 18, + "width": 14, + "height": 116 }, "selectCpu": { "left": 19, diff --git a/src/main/resources/assets/ae2/screens/crafting_cpu.json b/src/main/resources/assets/ae2/screens/crafting_cpu.json index 1e522d02eb9..25c55bb75d8 100644 --- a/src/main/resources/assets/ae2/screens/crafting_cpu.json +++ b/src/main/resources/assets/ae2/screens/crafting_cpu.json @@ -21,10 +21,10 @@ "height": 20 }, "scrollbar": { - "left": 218, - "top": 19, - "width": 12, - "height": 137 + "left": 217, + "top": 18, + "width": 14, + "height": 139 } } } diff --git a/src/main/resources/assets/ae2/screens/crafting_status.json b/src/main/resources/assets/ae2/screens/crafting_status.json index 4ba5e684b0d..83faad617ed 100644 --- a/src/main/resources/assets/ae2/screens/crafting_status.json +++ b/src/main/resources/assets/ae2/screens/crafting_status.json @@ -19,10 +19,10 @@ "height": 164 }, "selectCpuScrollbar": { - "left": -16, - "top": 23, - "width": 12, - "height": 137 + "left": -17, + "top": 22, + "width": 14, + "height": 139 } }, "text": { diff --git a/src/main/resources/assets/ae2/screens/network_status.json b/src/main/resources/assets/ae2/screens/network_status.json index 85b52b65644..0f673896dda 100644 --- a/src/main/resources/assets/ae2/screens/network_status.json +++ b/src/main/resources/assets/ae2/screens/network_status.json @@ -45,9 +45,10 @@ }, "widgets": { "scrollbar": { - "left": 175, - "top": 39, - "height": 78 + "left": 174, + "top": 38, + "width": 14, + "height": 80 } } } diff --git a/src/main/resources/assets/ae2/screens/terminals/base_terminal.json b/src/main/resources/assets/ae2/screens/terminals/base_terminal.json index e1fd7c320cc..d543d14e784 100644 --- a/src/main/resources/assets/ae2/screens/terminals/base_terminal.json +++ b/src/main/resources/assets/ae2/screens/terminals/base_terminal.json @@ -37,8 +37,9 @@ }, "widgets": { "scrollbar": { - "left": 175, - "top": 18 + "left": 174, + "top": 17, + "width": 14 }, "craftingStatus": { "left": 170, diff --git a/src/main/resources/assets/ae2/screens/terminals/encoding/processing.json b/src/main/resources/assets/ae2/screens/terminals/encoding/processing.json index 0ad3781f8b6..0ac1c1adbc8 100644 --- a/src/main/resources/assets/ae2/screens/terminals/encoding/processing.json +++ b/src/main/resources/assets/ae2/screens/terminals/encoding/processing.json @@ -77,9 +77,10 @@ }, "widgets": { "processingPatternModeScrollbar": { - "left": 17, - "bottom": 156, - "height": 52 + "left": 16, + "bottom": 157, + "height": 54, + "width": 9 }, "processingCycleOutput": { "left": 127, diff --git a/src/main/resources/assets/ae2/screens/terminals/encoding/stonecutting.json b/src/main/resources/assets/ae2/screens/terminals/encoding/stonecutting.json index 7406483c633..0cc8e919265 100644 --- a/src/main/resources/assets/ae2/screens/terminals/encoding/stonecutting.json +++ b/src/main/resources/assets/ae2/screens/terminals/encoding/stonecutting.json @@ -9,9 +9,10 @@ }, "widgets": { "stonecuttingPatternModeScrollbar": { - "left": 119, - "bottom": 157, - "height": 54 + "left": 118, + "bottom": 158, + "width": 9, + "height": 56 } } } diff --git a/src/main/resources/assets/ae2/screens/terminals/pattern_access_terminal.json b/src/main/resources/assets/ae2/screens/terminals/pattern_access_terminal.json index f4052c11748..f4b05402818 100644 --- a/src/main/resources/assets/ae2/screens/terminals/pattern_access_terminal.json +++ b/src/main/resources/assets/ae2/screens/terminals/pattern_access_terminal.json @@ -15,8 +15,9 @@ }, "widgets": { "scrollbar": { - "left": 175, - "top": 18 + "left": 174, + "top": 17, + "width": 14 }, "search": { "left": 104, diff --git a/src/main/resources/assets/ae2/textures/gui/sprites/small_scroller.png b/src/main/resources/assets/ae2/textures/gui/sprites/scroll_handle.png similarity index 100% rename from src/main/resources/assets/ae2/textures/gui/sprites/small_scroller.png rename to src/main/resources/assets/ae2/textures/gui/sprites/scroll_handle.png diff --git a/src/main/resources/assets/ae2/textures/gui/sprites/scroll_handle.png.mcmeta b/src/main/resources/assets/ae2/textures/gui/sprites/scroll_handle.png.mcmeta new file mode 100644 index 00000000000..4db672b5d30 --- /dev/null +++ b/src/main/resources/assets/ae2/textures/gui/sprites/scroll_handle.png.mcmeta @@ -0,0 +1,15 @@ +{ + "gui": { + "scaling": { + "type": "nine_slice", + "width": 7, + "height": 15, + "border": { + "left": 2, + "top": 2, + "right": 2, + "bottom": 1 + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ae2/textures/gui/sprites/small_scroller_disabled.png b/src/main/resources/assets/ae2/textures/gui/sprites/scroll_handle_disabled.png similarity index 100% rename from src/main/resources/assets/ae2/textures/gui/sprites/small_scroller_disabled.png rename to src/main/resources/assets/ae2/textures/gui/sprites/scroll_handle_disabled.png diff --git a/src/main/resources/assets/ae2/textures/gui/sprites/scroll_handle_disabled.png.mcmeta b/src/main/resources/assets/ae2/textures/gui/sprites/scroll_handle_disabled.png.mcmeta new file mode 100644 index 00000000000..4db672b5d30 --- /dev/null +++ b/src/main/resources/assets/ae2/textures/gui/sprites/scroll_handle_disabled.png.mcmeta @@ -0,0 +1,15 @@ +{ + "gui": { + "scaling": { + "type": "nine_slice", + "width": 7, + "height": 15, + "border": { + "left": 2, + "top": 2, + "right": 2, + "bottom": 1 + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ae2/textures/gui/sprites/sunken_panel_dark.png b/src/main/resources/assets/ae2/textures/gui/sprites/sunken_panel_dark.png new file mode 100644 index 00000000000..302c8adfd22 Binary files /dev/null and b/src/main/resources/assets/ae2/textures/gui/sprites/sunken_panel_dark.png differ diff --git a/src/main/resources/assets/ae2/textures/gui/sprites/sunken_panel_dark.png.mcmeta b/src/main/resources/assets/ae2/textures/gui/sprites/sunken_panel_dark.png.mcmeta new file mode 100644 index 00000000000..9976ebf09a3 --- /dev/null +++ b/src/main/resources/assets/ae2/textures/gui/sprites/sunken_panel_dark.png.mcmeta @@ -0,0 +1,10 @@ +{ + "gui": { + "scaling": { + "type": "nine_slice", + "width": 64, + "height": 64, + "border": 1 + } + } +} \ No newline at end of file