From 4cf4e2ada24593872cccf2b3734752661553cdd7 Mon Sep 17 00:00:00 2001 From: Martin Robertz Date: Wed, 28 Aug 2024 22:45:17 +0200 Subject: [PATCH 1/2] update --- dependencies.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 2550361e2ad..90cc399ff42 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -11,7 +11,7 @@ dependencies { compileOnly('com.github.GTNewHorizons:BuildCraft:7.1.39:dev') {transitive = false} compileOnly('com.github.GTNewHorizons:ForestryMC:4.9.7:dev') {transitive = false} // required to compile CraftingV2Tests.java now compileOnly('com.github.GTNewHorizons:ForgeMultipart:1.5.0:dev') {transitive = false} - compileOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.49.29:dev') {transitive = false} + compileOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.49.33:dev') {transitive = false} compileOnly('com.github.GTNewHorizons:Jabba:1.4.6:dev') {transitive = false} compileOnly('com.github.GTNewHorizons:inventory-tweaks:1.6.2:api') {transitive = false} compileOnly('com.github.GTNewHorizons:OpenComputers:1.10.21-GTNH:api') {transitive = false} @@ -35,13 +35,13 @@ dependencies { functionalTestImplementation('org.junit.platform:junit-platform-engine') functionalTestImplementation('org.junit.platform:junit-platform-launcher') functionalTestImplementation('org.junit.platform:junit-platform-reporting') - functionalTestImplementation('com.github.GTNewHorizons:GT5-Unofficial:5.09.49.29:dev') { + functionalTestImplementation('com.github.GTNewHorizons:GT5-Unofficial:5.09.49.33:dev') { exclude module: "Applied-Energistics-2-Unofficial" } - runtimeOnlyNonPublishable("com.github.GTNewHorizons:DuraDisplay:1.3.2:dev") + runtimeOnlyNonPublishable("com.github.GTNewHorizons:DuraDisplay:1.3.3:dev") runtimeOnlyNonPublishable('com.github.GTNewHorizons:Baubles:1.0.4:dev') runtimeOnlyNonPublishable('thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev') runtimeOnlyNonPublishable('com.github.GTNewHorizons:ThaumicEnergistics:1.6.22-GTNH:dev') { transitive = false } - runtimeOnlyNonPublishable('com.github.GTNewHorizons:AE2FluidCraft-Rework:1.3.29-gtnh:dev') { transitive = false } + runtimeOnlyNonPublishable('com.github.GTNewHorizons:AE2FluidCraft-Rework:1.3.33-gtnh:dev') { transitive = false } } From 71ea2eaed078681fb15c834d4a91f9d3e4a8a926 Mon Sep 17 00:00:00 2001 From: hiroscho Date: Sat, 31 Aug 2024 15:39:12 +0200 Subject: [PATCH 2/2] Feature/sort interfaces alphanum order (#563) * Add the ability to sort interfaces in the interface terminal by natural order * add zh_CN.lang localization * Add static instance of AlphanumComparator Remove code-specific header comment * Add library clarification * change alphanum icon --------- Co-authored-by: glowredman <35727266+glowredman@users.noreply.github.com> Co-authored-by: MCTBL --- src/main/java/appeng/api/config/Settings.java | 4 +- .../java/appeng/api/config/StringOrder.java | 18 +++ .../implementations/GuiInterfaceTerminal.java | 33 +++++- .../client/gui/widgets/GuiImgButton.java | 14 +++ src/main/java/appeng/core/AEConfig.java | 2 + .../core/localization/ButtonToolTips.java | 6 +- .../java/appeng/util/AlphanumComparator.java | 109 ++++++++++++++++++ .../appliedenergistics2/lang/en_US.lang | 4 + .../appliedenergistics2/lang/zh_CN.lang | 4 + 9 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 src/main/java/appeng/api/config/StringOrder.java create mode 100644 src/main/java/appeng/util/AlphanumComparator.java diff --git a/src/main/java/appeng/api/config/Settings.java b/src/main/java/appeng/api/config/Settings.java index 16aadf63aad..d81dbd4c5b9 100644 --- a/src/main/java/appeng/api/config/Settings.java +++ b/src/main/java/appeng/api/config/Settings.java @@ -80,7 +80,9 @@ public enum Settings { PRIORITY_CARD_MODE(EnumSet.allOf(PriorityCardMode.class)), - TERMINAL_FONT_SIZE(EnumSet.allOf(TerminalFontSize.class)); + TERMINAL_FONT_SIZE(EnumSet.allOf(TerminalFontSize.class)), + + INTERFACE_TERMINAL_SECTION_ORDER(EnumSet.allOf(StringOrder.class)); private final EnumSet> values; diff --git a/src/main/java/appeng/api/config/StringOrder.java b/src/main/java/appeng/api/config/StringOrder.java new file mode 100644 index 00000000000..ff0e4b2f767 --- /dev/null +++ b/src/main/java/appeng/api/config/StringOrder.java @@ -0,0 +1,18 @@ +package appeng.api.config; + +import java.util.Comparator; + +import appeng.util.AlphanumComparator; + +public enum StringOrder { + + NATURAL(Comparator.naturalOrder()), + + ALPHANUM(AlphanumComparator.INSTANCE); + + public final Comparator comparator; + + StringOrder(Comparator comparator) { + this.comparator = comparator; + } +} diff --git a/src/main/java/appeng/client/gui/implementations/GuiInterfaceTerminal.java b/src/main/java/appeng/client/gui/implementations/GuiInterfaceTerminal.java index 77a5cb42f31..46c197a1ec1 100644 --- a/src/main/java/appeng/client/gui/implementations/GuiInterfaceTerminal.java +++ b/src/main/java/appeng/client/gui/implementations/GuiInterfaceTerminal.java @@ -17,6 +17,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; @@ -44,6 +45,7 @@ import appeng.api.AEApi; import appeng.api.config.ActionItems; import appeng.api.config.Settings; +import appeng.api.config.StringOrder; import appeng.api.config.TerminalStyle; import appeng.api.config.YesNo; import appeng.api.util.DimensionalCoord; @@ -105,7 +107,9 @@ public class GuiInterfaceTerminal extends AEBaseGui AppEng.MOD_ID, "textures/guis/newinterfaceterminal.png"); - private final InterfaceTerminalList masterList = new InterfaceTerminalList(); + private final InterfaceTerminalList masterList = new InterfaceTerminalList( + ((StringOrder) AEConfig.instance.settings + .getSetting(Settings.INTERFACE_TERMINAL_SECTION_ORDER)).comparator); private final MEGuiTextField searchFieldOutputs; private final MEGuiTextField searchFieldInputs; private final MEGuiTextField searchFieldNames; @@ -114,6 +118,7 @@ public class GuiInterfaceTerminal extends AEBaseGui private final GuiImgButton guiButtonBrokenRecipes; private final GuiImgButton terminalStyleBox; private final GuiImgButton searchStringSave; + private final GuiImgButton guiButtonSectionOrder; private boolean onlyMolecularAssemblers = false; private boolean onlyBrokenRecipes = false; private boolean online; @@ -179,6 +184,7 @@ public void onTextChange(final String oldText) { guiButtonAssemblersOnly = new GuiImgButton(0, 0, Settings.ACTIONS, null); guiButtonHideFull = new GuiImgButton(0, 0, Settings.ACTIONS, null); guiButtonBrokenRecipes = new GuiImgButton(0, 0, Settings.ACTIONS, null); + guiButtonSectionOrder = new GuiImgButton(0, 0, Settings.INTERFACE_TERMINAL_SECTION_ORDER, StringOrder.NATURAL); terminalStyleBox = new GuiImgButton(0, 0, Settings.TERMINAL_STYLE, null); @@ -224,8 +230,11 @@ public void initGui() { searchStringSave.xPosition = guiLeft - 18; searchStringSave.yPosition = terminalStyleBox.yPosition + 18; + guiButtonSectionOrder.xPosition = guiLeft - 18; + guiButtonSectionOrder.yPosition = searchStringSave.yPosition + 18; + guiButtonBrokenRecipes.xPosition = guiLeft - 18; - guiButtonBrokenRecipes.yPosition = searchStringSave.yPosition + 18; + guiButtonBrokenRecipes.yPosition = guiButtonSectionOrder.yPosition + 18; guiButtonHideFull.xPosition = guiLeft - 18; guiButtonHideFull.yPosition = guiButtonBrokenRecipes.yPosition + 18; @@ -243,6 +252,7 @@ public void initGui() { buttonList.add(guiButtonAssemblersOnly); buttonList.add(guiButtonHideFull); buttonList.add(guiButtonBrokenRecipes); + buttonList.add(guiButtonSectionOrder); buttonList.add(searchStringSave); buttonList.add(terminalStyleBox); } @@ -293,6 +303,7 @@ public void drawScreen(final int mouseX, final int mouseY, final float btn) { guiButtonBrokenRecipes.set( onlyBrokenRecipes ? ActionItems.TOGGLE_SHOW_ONLY_INVALID_PATTERN_OFF : ActionItems.TOGGLE_SHOW_ONLY_INVALID_PATTERN_ON); + guiButtonSectionOrder.set(AEConfig.instance.settings.getSetting(Settings.INTERFACE_TERMINAL_SECTION_ORDER)); terminalStyleBox.set(AEConfig.instance.settings.getSetting(Settings.TERMINAL_STYLE)); @@ -337,6 +348,10 @@ protected void actionPerformed(final GuiButton btn) { initGui(); } else if (btn == searchStringSave) { AEConfig.instance.preserveSearchBar = next == YesNo.YES; + } else if (btn == guiButtonSectionOrder) { + AEConfig.instance.settings.putSetting(iBtn.getSetting(), next); + masterList.changeSectionComparator(((StringOrder) next).comparator); + masterList.markDirty(); } iBtn.set(next); @@ -962,16 +977,26 @@ public void setTextFieldValue(final String displayName, final int mousex, final private class InterfaceTerminalList { private final Map list = new HashMap<>(); - private final Map sections = new TreeMap<>(); + private Map sections; private final List visibleSections = new ArrayList<>(); private boolean isDirty; private int height; private InterfaceTerminalEntry hoveredEntry; - InterfaceTerminalList() { + InterfaceTerminalList(Comparator comparator) { + this.sections = comparator == null ? new TreeMap<>() : new TreeMap<>(comparator); this.isDirty = true; } + void changeSectionComparator(Comparator comparator) { + if ((this.sections instanceof TreeMap t) && !Objects.equals(comparator, t.comparator())) { + TreeMap map = comparator == null ? new TreeMap<>() + : new TreeMap<>(comparator); + map.putAll(this.sections); + this.sections = map; + } + } + /** * Performs a full update. */ diff --git a/src/main/java/appeng/client/gui/widgets/GuiImgButton.java b/src/main/java/appeng/client/gui/widgets/GuiImgButton.java index 990ddcc41c2..bd2d3595992 100644 --- a/src/main/java/appeng/client/gui/widgets/GuiImgButton.java +++ b/src/main/java/appeng/client/gui/widgets/GuiImgButton.java @@ -49,6 +49,7 @@ import appeng.api.config.SortDir; import appeng.api.config.SortOrder; import appeng.api.config.StorageFilter; +import appeng.api.config.StringOrder; import appeng.api.config.TerminalStyle; import appeng.api.config.TypeFilter; import appeng.api.config.ViewItems; @@ -769,6 +770,19 @@ public GuiImgButton(final int x, final int y, final Enum idx, final Enum val) { ButtonToolTips.PriorityCardMode, ButtonToolTips.PriorityCardMode_Dec); + this.registerApp( + 64, + Settings.INTERFACE_TERMINAL_SECTION_ORDER, + StringOrder.NATURAL, + ButtonToolTips.StringOrder, + ButtonToolTips.StringOrderNatural); + this.registerApp( + 16, + Settings.INTERFACE_TERMINAL_SECTION_ORDER, + StringOrder.ALPHANUM, + ButtonToolTips.StringOrder, + ButtonToolTips.StringOrderAlphanum); + } } diff --git a/src/main/java/appeng/core/AEConfig.java b/src/main/java/appeng/core/AEConfig.java index ac7f07cd2ca..5d2ef45ceb7 100644 --- a/src/main/java/appeng/core/AEConfig.java +++ b/src/main/java/appeng/core/AEConfig.java @@ -27,6 +27,7 @@ import appeng.api.config.SearchBoxMode; import appeng.api.config.Settings; import appeng.api.config.SortDir; +import appeng.api.config.StringOrder; import appeng.api.config.TerminalFontSize; import appeng.api.config.TerminalStyle; import appeng.api.config.YesNo; @@ -158,6 +159,7 @@ public AEConfig(final File configFile) { this.settings.registerSetting(Settings.CRAFTING_SORT_BY, CraftingSortOrder.NAME); this.settings.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING); this.settings.registerSetting(Settings.TERMINAL_FONT_SIZE, TerminalFontSize.SMALL); + this.settings.registerSetting(Settings.INTERFACE_TERMINAL_SECTION_ORDER, StringOrder.NATURAL); this.spawnChargedChance = (float) (1.0 - this.get("worldGen", "spawnChargedChance", 1.0 - this.spawnChargedChance) diff --git a/src/main/java/appeng/core/localization/ButtonToolTips.java b/src/main/java/appeng/core/localization/ButtonToolTips.java index e8acd952644..8fca6e73f6b 100644 --- a/src/main/java/appeng/core/localization/ButtonToolTips.java +++ b/src/main/java/appeng/core/localization/ButtonToolTips.java @@ -214,7 +214,11 @@ public enum ButtonToolTips { PriorityCardMode_Inc, PriorityCardMode_Dec, ToFollow, - ToUnfollow; + ToUnfollow, + + StringOrder, + StringOrderNatural, + StringOrderAlphanum; private final String root; diff --git a/src/main/java/appeng/util/AlphanumComparator.java b/src/main/java/appeng/util/AlphanumComparator.java new file mode 100644 index 00000000000..5785323e649 --- /dev/null +++ b/src/main/java/appeng/util/AlphanumComparator.java @@ -0,0 +1,109 @@ +package appeng.util; +// This code is copied from the library https://github.com/metamx/alphanum +// spotless:off +/* + * The Alphanum Algorithm is an improved sorting algorithm for strings + * containing numbers. Instead of sorting numbers in ASCII order like + * a standard sort, this algorithm sorts numbers in numeric order. + * + * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +// spotless:on + +import java.util.Comparator; + +/** + * This is an updated version with enhancements made by Daniel Migowski, Andre Bogus, and David Koelle + */ +public class AlphanumComparator implements Comparator { + + public final static AlphanumComparator INSTANCE = new AlphanumComparator(); + + private final boolean isDigit(char ch) { + return ch >= 48 && ch <= 57; + } + + /** + * Length of string is passed in for improved efficiency (only need to calculate it once) * + */ + private final String getChunk(String s, int slength, int marker) { + StringBuilder chunk = new StringBuilder(); + char c = s.charAt(marker); + chunk.append(c); + marker++; + if (isDigit(c)) { + while (marker < slength) { + c = s.charAt(marker); + if (!isDigit(c)) break; + chunk.append(c); + marker++; + } + } else { + while (marker < slength) { + c = s.charAt(marker); + if (isDigit(c)) break; + chunk.append(c); + marker++; + } + } + return chunk.toString(); + } + + public int compare(String s1, String s2) { + if (s1 == null || s2 == null) { + return 0; + } + + int thisMarker = 0; + int thatMarker = 0; + int s1Length = s1.length(); + int s2Length = s2.length(); + + while (thisMarker < s1Length && thatMarker < s2Length) { + String thisChunk = getChunk(s1, s1Length, thisMarker); + thisMarker += thisChunk.length(); + + String thatChunk = getChunk(s2, s2Length, thatMarker); + thatMarker += thatChunk.length(); + + // If both chunks contain numeric characters, sort them numerically + int result = 0; + if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) { + // Simple chunk comparison by length. + int thisChunkLength = thisChunk.length(); + result = thisChunkLength - thatChunk.length(); + // If equal, the first different number counts + if (result == 0) { + for (int i = 0; i < thisChunkLength; i++) { + result = thisChunk.charAt(i) - thatChunk.charAt(i); + if (result != 0) { + return result; + } + } + } + } else { + result = thisChunk.compareTo(thatChunk); + } + + if (result != 0) return result; + } + + return s1Length - s2Length; + } +} diff --git a/src/main/resources/assets/appliedenergistics2/lang/en_US.lang b/src/main/resources/assets/appliedenergistics2/lang/en_US.lang index e7508de6a34..3aa2e61f2e1 100644 --- a/src/main/resources/assets/appliedenergistics2/lang/en_US.lang +++ b/src/main/resources/assets/appliedenergistics2/lang/en_US.lang @@ -527,6 +527,10 @@ gui.tooltips.appliedenergistics2.MultiplyOrDividePatternHint=If it's positive, i gui.tooltips.appliedenergistics2.ToFollow=Click to follow this craft and receive message when it is complete\nYou are not following this crafting job right now gui.tooltips.appliedenergistics2.ToUnfollow=Click to stop following this craft\nYou are following this crafting job and will receive chat message when it's complete +gui.tooltips.appliedenergistics2.StringOrder=Sorting +gui.tooltips.appliedenergistics2.StringOrderNatural=Default +gui.tooltips.appliedenergistics2.StringOrderAlphanum=Natural Order + # Units gui.appliedenergistics2.units.appliedenergstics=AE gui.appliedenergistics2.units.ic2=Energy Units diff --git a/src/main/resources/assets/appliedenergistics2/lang/zh_CN.lang b/src/main/resources/assets/appliedenergistics2/lang/zh_CN.lang index 9626ed4ee2f..8c6f2aeb9b4 100644 --- a/src/main/resources/assets/appliedenergistics2/lang/zh_CN.lang +++ b/src/main/resources/assets/appliedenergistics2/lang/zh_CN.lang @@ -527,6 +527,10 @@ gui.tooltips.appliedenergistics2.MultiplyOrDividePatternHint=如果是正数,就 gui.tooltips.appliedenergistics2.ToFollow=当前并未订阅该合成的消息\n当该合成完成时将不会接收到消息提示\n点击即可订阅 gui.tooltips.appliedenergistics2.ToUnfollow=当前已经订阅该合成的消息\n当该合成完成时将会接收到消息提示\n点击即可取消 +gui.tooltips.appliedenergistics2.StringOrder=排序方式 +gui.tooltips.appliedenergistics2.StringOrderNatural=默认排序 +gui.tooltips.appliedenergistics2.StringOrderAlphanum=自然数序 + # Units gui.appliedenergistics2.units.appliedenergstics=AE gui.appliedenergistics2.units.ic2=EU