Skip to content
This repository was archived by the owner on Dec 30, 2022. It is now read-only.

Commit 1d424dd

Browse files
author
DeathsGun
committed
Implemented mod searching
Also improved the action buttons in the UI TODO: allow updating of mods
1 parent b143208 commit 1d424dd

17 files changed

Lines changed: 209 additions & 72 deletions

File tree

build.gradle

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,9 @@ version = project.mod_version
1111
group = project.maven_group
1212

1313
repositories {
14-
//maven {
15-
// name = "TerraformersMC"
16-
// url = "https://maven.terraformersmc.com/releases/"
17-
//}
1814
maven {
19-
name = "TerraformersMC Fallback"
20-
url = "https://raw.githubusercontent.com/TerraformersMC/Archive/main/releases/"
15+
name = "TerraformersMC"
16+
url = "https://maven.terraformersmc.com/releases/"
2117
}
2218
}
2319

src/main/java/xyz/deathsgun/modmanager/api/manipulation/ManipulationTask.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@ public abstract class ManipulationTask {
2626

2727
protected final String id;
2828
protected final SummarizedMod subject;
29-
private final @Nullable ErrorHandler errorHandler;
29+
private final @Nullable TaskCallback taskCallback;
3030
private final boolean debugMode;
3131
protected Logger logger;
3232
protected TaskState state = TaskState.SCHEDULED;
33+
private Exception error;
3334

34-
public ManipulationTask(@NotNull String id, @NotNull SummarizedMod subject, @Nullable ErrorHandler errorHandler) {
35+
public ManipulationTask(@NotNull String id, @NotNull SummarizedMod subject, @Nullable TaskCallback taskCallback) {
3536
this.id = id;
3637
this.subject = subject;
37-
this.errorHandler = errorHandler;
38+
this.taskCallback = taskCallback;
3839
this.debugMode = FabricLoader.getInstance().isDevelopmentEnvironment();
3940
}
4041

@@ -45,11 +46,15 @@ public final void executeTask() {
4546
this.state = TaskState.RUNNING;
4647
execute();
4748
this.state = TaskState.FINISHED;
49+
if (taskCallback != null) {
50+
taskCallback.onTaskFinish(this);
51+
}
4852
} catch (Exception e) {
49-
e.printStackTrace();
53+
this.error = e;
54+
logger.error("Error while executing task for {}", subject.slug(), e);
5055
this.state = TaskState.FAILED;
51-
if (errorHandler != null) {
52-
errorHandler.onError(e);
56+
if (taskCallback != null) {
57+
taskCallback.onTaskFinish(this);
5358
}
5459
}
5560
}
@@ -73,6 +78,10 @@ public void debug(String message, Object... o) {
7378
logger.info(message, o);
7479
}
7580

81+
public Exception getException() {
82+
return error;
83+
}
84+
7685
public enum TaskState {
7786
SCHEDULED, RUNNING, FINISHED, FAILED
7887
}

src/main/java/xyz/deathsgun/modmanager/api/manipulation/NetworkTask.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ public abstract class NetworkTask extends ManipulationTask {
2828

2929
protected final HttpClient http;
3030

31-
public NetworkTask(@NotNull String id, @NotNull SummarizedMod subject, @Nullable ErrorHandler errorHandler) {
32-
super(id, subject, errorHandler);
31+
public NetworkTask(@NotNull String id, @NotNull SummarizedMod subject, @Nullable TaskCallback taskCallback) {
32+
super(id, subject, taskCallback);
3333
this.http = HttpClient.newHttpClient();
3434
}
3535

src/main/java/xyz/deathsgun/modmanager/api/manipulation/ErrorHandler.java renamed to src/main/java/xyz/deathsgun/modmanager/api/manipulation/TaskCallback.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
package xyz.deathsgun.modmanager.api.manipulation;
1818

19-
public interface ErrorHandler {
19+
public interface TaskCallback {
2020

21-
void onError(Exception error);
21+
void onTaskFinish(ManipulationTask task);
2222

2323
}

src/main/java/xyz/deathsgun/modmanager/gui/ModDetailScreen.java

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import net.minecraft.text.*;
2929
import net.minecraft.util.Identifier;
3030
import xyz.deathsgun.modmanager.ModManager;
31+
import xyz.deathsgun.modmanager.api.manipulation.ManipulationTask;
3132
import xyz.deathsgun.modmanager.api.mod.Category;
3233
import xyz.deathsgun.modmanager.api.mod.DetailedMod;
3334
import xyz.deathsgun.modmanager.api.mod.SummarizedMod;
@@ -42,12 +43,12 @@
4243
public class ModDetailScreen extends Screen {
4344

4445
private static final Pattern HTML_PATTERN = Pattern.compile("<.*?>.*?</.*?>|</*.?>");
45-
private final SummarizedMod summarizedMod;
46+
final SummarizedMod summarizedMod;
4647
private final Screen previousScreen;
4748
private ButtonWidget actionButton;
4849
private DetailedMod detailedMod;
4950
private DescriptionWidget descriptionWidget;
50-
private Exception exception;
51+
Exception exception;
5152

5253
public ModDetailScreen(Screen previousScreen, SummarizedMod mod) {
5354
super(new LiteralText(mod.name()));
@@ -75,40 +76,48 @@ protected void init() {
7576

7677
this.actionButton = this.addDrawableChild(new ButtonWidget(this.width - buttonX - 150, this.height - 28, 150, 20, new TranslatableText("modmanager.message.install"),
7778
this::handleActionClick));
78-
79-
//TODO: If only remove available show only that button
79+
this.updateActionButton();
8080
}
8181

8282
private void handleActionClick(ButtonWidget buttonWidget) {
83-
if (exception != null) {
84-
MinecraftClient.getInstance().openScreen(new ModManagerErrorScreen(this, exception));
85-
return;
86-
}
8783
buttonWidget.active = false;
88-
buttonWidget.setMessage(new TranslatableText("modmanager.message.installing"));
89-
ModManager.getModManipulationManager().installMod(summarizedMod, this::handleErrors);
84+
String key = ((TranslatableText) buttonWidget.getMessage()).getKey();
85+
switch (key) {
86+
case "modmanager.message.install" -> {
87+
buttonWidget.setMessage(new TranslatableText("modmanager.message.installing"));
88+
ModManager.getModManipulationManager().installMod(summarizedMod, this::handleTaskResult);
89+
}
90+
case "modmanager.message.remove" -> {
91+
buttonWidget.setMessage(new TranslatableText("modmanager.message.removing"));
92+
ModManager.getModManipulationManager().removeMod(summarizedMod, this::handleTaskResult);
93+
}
94+
case "modmanager.message.showError" -> {
95+
buttonWidget.active = true;
96+
MinecraftClient.getInstance().openScreen(new ModManagerErrorScreen(this, exception));
97+
}
98+
case "modmanager.message.update" -> buttonWidget.setMessage(new TranslatableText("modmanager.message.updating"));
99+
}
90100
}
91101

92-
private void handleErrors(Exception e) {
93-
this.exception = e;
94-
ModManager.getManipulationService().removeTasks(summarizedMod.id());
102+
private void handleTaskResult(ManipulationTask task) {
103+
this.exception = task.getException();
104+
updateActionButton();
95105
}
96106

97-
@Override
98-
public void tick() {
99-
super.tick();
100-
if (ModManager.getModManipulationManager().isInstalled(summarizedMod)) {
101-
actionButton.setMessage(new TranslatableText("modmanager.message.remove"));
102-
actionButton.active = true;
103-
return;
104-
}
107+
void updateActionButton() {
108+
actionButton.active = true;
105109
if (exception != null) {
106110
actionButton.setMessage(new TranslatableText("modmanager.message.showError"));
107-
actionButton.active = true;
111+
return;
112+
}
113+
if (ModManager.getModManipulationManager().isInstalled(summarizedMod)) {
114+
if (ModManager.getModManipulationManager().isMarkedUninstalled(summarizedMod)) {
115+
actionButton.setMessage(new TranslatableText("modmanager.message.install"));
116+
}
117+
actionButton.setMessage(new TranslatableText("modmanager.message.remove"));
108118
return;
109119
}
110120
actionButton.setMessage(new TranslatableText("modmanager.message.install"));
111-
actionButton.active = true;
112121
}
113122

114123
@Override

src/main/java/xyz/deathsgun/modmanager/gui/ModManagerErrorScreen.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@
2222
import net.minecraft.client.util.math.MatrixStack;
2323
import net.minecraft.text.TranslatableText;
2424
import org.apache.commons.lang3.exception.ExceptionUtils;
25+
import xyz.deathsgun.modmanager.ModManager;
2526
import xyz.deathsgun.modmanager.gui.widget.DescriptionWidget;
2627

2728
import java.util.Objects;
2829

2930
public class ModManagerErrorScreen extends Screen {
3031

3132
private final Exception exception;
32-
private final Screen parentScreen;
33+
private Screen parentScreen;
3334
private DescriptionWidget descriptionWidget;
3435

3536
public ModManagerErrorScreen(Screen screen, Exception exception) {
@@ -46,6 +47,21 @@ protected void init() {
4647
descriptionWidget = this.addSelectableChild(new DescriptionWidget(client, (int) (width * 0.90), height, (int) (height * 0.1), this.height - 36, 9, error));
4748
descriptionWidget.setLeftPos((int) (this.width * 0.05));
4849
this.addDrawableChild(new ButtonWidget(this.width / 2 - 154, this.height - 28, 150, 20, ScreenTexts.CANCEL, button -> this.onClose()));
50+
this.addDrawableChild(new ButtonWidget(this.width / 2, this.height - 28, 150, 20,
51+
new TranslatableText("modmanager.message.goBackAndTryAgain"), button -> {
52+
if (this.parentScreen instanceof ModDetailScreen) {
53+
this.clearErrors();
54+
}
55+
this.onClose();
56+
}));
57+
}
58+
59+
private void clearErrors() {
60+
ModDetailScreen screen = (ModDetailScreen) parentScreen;
61+
screen.exception = null;
62+
ModManager.getManipulationService().removeTasks(screen.summarizedMod.id());
63+
screen.updateActionButton();
64+
this.parentScreen = screen;
4965
}
5066

5167
@Override

src/main/java/xyz/deathsgun/modmanager/gui/ModsOverviewScreen.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import net.minecraft.client.font.TextRenderer;
2020
import net.minecraft.client.gui.screen.Screen;
2121
import net.minecraft.client.gui.widget.ButtonWidget;
22+
import net.minecraft.client.gui.widget.TextFieldWidget;
23+
import net.minecraft.client.input.KeyboardInput;
2224
import net.minecraft.client.util.math.MatrixStack;
2325
import net.minecraft.text.TranslatableText;
2426
import org.apache.logging.log4j.LogManager;
@@ -38,6 +40,7 @@ public class ModsOverviewScreen extends Screen implements IListScreen {
3840
private ModListEntry selectedMod;
3941
private CategoryListWidget categoryListWidget;
4042
private CategoryListEntry selectedCategory;
43+
private TextFieldWidget searchBox;
4144
private int paneWidth;
4245
private int rightPaneX;
4346

@@ -51,31 +54,43 @@ protected void init() {
5154
Objects.requireNonNull(this.client).keyboard.setRepeatEvents(true);
5255
paneWidth = this.width / 4;
5356
rightPaneX = this.paneWidth + 10;
57+
int searchBoxWidth = paneWidth + 40;
58+
this.searchBox = this.addSelectableChild(new TextFieldWidget(textRenderer, 5, 5, searchBoxWidth, 20, new TranslatableText("modmanager.message.search")));
59+
this.searchBox.setChangedListener(this::handleSearch);
60+
5461
this.categoryListWidget = this.addSelectableChild(new CategoryListWidget(this.client, paneWidth, this.height, 30, this.height - 10, 14, this));
5562
this.categoryListWidget.setLeftPos(0);
63+
5664
int modListWidth = this.width - paneWidth - 20;
5765
this.modListWidget = this.addSelectableChild(new ModListWidget(this.client, modListWidth, this.height, 30, this.height - 40, 36, this));
5866
this.modListWidget.setLeftPos(rightPaneX);
5967
this.categoryListWidget.init();
6068
this.modListWidget.init();
69+
6170
this.addDrawableChild(new ButtonWidget(rightPaneX, this.height - 30, modListWidth / 2 - 10, 20,
6271
new TranslatableText("modmanager.page.previous"), button -> this.modListWidget.showPreviousPage()));
6372
this.addDrawableChild(new ButtonWidget(rightPaneX + modListWidth / 2, this.height - 30, modListWidth / 2, 20,
6473
new TranslatableText("modmanager.page.next"), button -> this.modListWidget.showNextPage()));
6574
}
6675

76+
private void handleSearch(String query) {
77+
this.modListWidget.searchMods(query);
78+
}
79+
6780
@Override
6881
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
6982
this.renderBackground(matrices);
7083
TextRenderer font = Objects.requireNonNull(client).textRenderer;
7184
font.draw(matrices, new TranslatableText("modmanager.categories"), 5, 29 - font.fontHeight, 0xFFFFFF);
7285
this.categoryListWidget.render(matrices, mouseX, mouseY, delta);
7386
this.modListWidget.render(matrices, mouseX, mouseY, delta);
87+
this.searchBox.render(matrices, mouseX, mouseY, delta);
7488
super.render(matrices, mouseX, mouseY, delta);
7589
}
7690

7791
@Override
7892
public void tick() {
93+
this.searchBox.tick();
7994
}
8095

8196
@Override
@@ -89,6 +104,8 @@ public void onClose() {
89104
public <E> void updateSelectedEntry(Object widget, E entry) {
90105
if (widget == this.categoryListWidget) {
91106
if (entry != null) {
107+
this.searchBox.setText("");
108+
this.searchBox.setTextFieldFocused(false);
92109
this.selectedCategory = (CategoryListEntry) entry;
93110
this.modListWidget.setCategory(selectedCategory.getCategory(), false);
94111
}

src/main/java/xyz/deathsgun/modmanager/gui/widget/ModListWidget.java

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class ModListWidget extends BetterListWidget<ModListEntry> {
3232
private final ArrayList<SummarizedMod> mods = new ArrayList<>();
3333
private int page = 0;
3434
private Category category;
35+
private String query;
3536

3637
public ModListWidget(MinecraftClient client, int width, int height, int top, int bottom, int itemHeight, ModsOverviewScreen parentScreen) {
3738
super(client, width, height, top, bottom, itemHeight, parentScreen);
@@ -43,23 +44,42 @@ public void init() {
4344
}
4445

4546
public void setCategory(Category category, boolean force) {
46-
setScrollAmount(0.0 * Math.max(0, this.getMaxPosition() - (this.bottom - this.top - 4)));
47+
setScrollAmount(0.0);
4748
if (this.category != null && Objects.equals(this.category.id(), category.id()) && !force) {
4849
return;
4950
}
5051
this.category = category;
51-
this.mods.clear();
52-
for (int i = 0; i < this.getEntryCount(); i++) {
53-
this.remove(i);
52+
this.clearMods();
53+
try {
54+
ModManager.getModProvider().getMods(category, page, limit)
55+
.forEach(mod -> this.addEntry(new ModListEntry(this, mod)));
56+
} catch (Exception e) {
57+
e.printStackTrace();
5458
}
55-
this.clearEntries();
59+
}
60+
61+
public void searchMods(String query) {
62+
if (query == null || "".equals(query)) {
63+
return;
64+
}
65+
setScrollAmount(0.0);
66+
this.clearMods();
5667
try {
57-
ModManager.getModProvider().getMods(category, page, limit).forEach(mod -> this.addEntry(new ModListEntry(this, mod)));
68+
this.category = null;
69+
ModManager.getModProvider().getMods(query, page, limit)
70+
.forEach(mod -> this.addEntry(new ModListEntry(this, mod)));
5871
} catch (Exception e) {
5972
e.printStackTrace();
6073
}
6174
}
6275

76+
private void clearMods() {
77+
this.mods.clear();
78+
for (int i = 0; i < this.getEntryCount(); i++) {
79+
this.remove(i);
80+
}
81+
this.clearEntries();
82+
}
6383

6484
@Override
6585
public int addEntry(ModListEntry entry) {
@@ -89,15 +109,23 @@ protected ModListEntry remove(int index) {
89109

90110
public void showNextPage() {
91111
this.page++;
92-
this.setCategory(category, true);
112+
if (this.category != null) {
113+
this.setCategory(category, true);
114+
return;
115+
}
116+
this.searchMods(this.query);
93117
}
94118

95119
public void showPreviousPage() {
96120
this.page--;
97121
if (this.page < 0) {
98122
page = 0;
99123
}
100-
this.setCategory(category, true);
124+
if (this.category != null) {
125+
this.setCategory(category, true);
126+
return;
127+
}
128+
this.searchMods(this.query);
101129
}
102130

103131
public void close() {

src/main/java/xyz/deathsgun/modmanager/gui/widget/better/IListScreen.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ public interface IListScreen {
2525
<E> void updateSelectedEntry(Object widget, E entry);
2626

2727
<E> E getEntry(Object widget);
28+
2829
}

0 commit comments

Comments
 (0)