aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/main/java/me/shedaniel/rei
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2025-07-01 14:49:29 +0800
committershedaniel <daniel@shedaniel.me>2025-07-01 14:49:29 +0800
commit47501412b83fb0507e1e7fe3884255fff24eec2e (patch)
tree7625e32b69a12a6f58f40c2f197e5205954f1835 /runtime/src/main/java/me/shedaniel/rei
parentd9d53c69260d038268543dd761a32ae9fd6663b4 (diff)
downloadRoughlyEnoughItems-feature/calculator.tar.gz
RoughlyEnoughItems-feature/calculator.tar.bz2
RoughlyEnoughItems-feature/calculator.zip
WIP Calculatorfeature/calculator
Diffstat (limited to 'runtime/src/main/java/me/shedaniel/rei')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java6
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java45
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/CalculatorPanel.java124
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FadingFavoritesPanelButton.java13
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FavoritesAddPanel.java143
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FavoritesPanel.java130
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FavoritesTogglePanelButton.java110
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/rows/FavoritesPanelEmptyRow.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/rows/FavoritesPanelEntriesRow.java10
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/rows/FavoritesPanelRow.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/rows/FavoritesPanelSectionRow.java6
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/rows/FavoritesPanelSeparatorRow.java4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/trash/TrashWidget.java4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/CalculatorDisplay.java130
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/CalculatorDisplayUtils.java139
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchField.java40
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java11
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/util/ColorUtils.java19
21 files changed, 628 insertions, 317 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
index 4b500fa1f..627cb2981 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
@@ -329,6 +329,11 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
}
@Override
+ public boolean isCalculatorPanelEnabled() {
+ return advanced.layout.calculatorPanel;
+ }
+
+ @Override
public ModifierKeyCode getFavoriteKeyCode() {
return basics.keyBindings.favoriteKeybind == null ? ModifierKeyCode.unknown() : basics.keyBindings.favoriteKeybind;
}
@@ -693,6 +698,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
@Comment("Merges displays with equal contents under 1 display.")
public boolean mergeDisplayUnderOne = true;
public FavoriteAddWidgetMode favoriteAddWidgetMode = FavoriteAddWidgetMode.ALWAYS_VISIBLE;
+ public boolean calculatorPanel = true;
}
public static class Accessibility {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java
index fe905b5cc..369d084af 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java
@@ -428,7 +428,7 @@ public abstract class ScreenOverlayImpl extends ScreenOverlay {
if (REIRuntimeImpl.getSearchField().keyReleased(keyCode, scanCode, modifiers))
return true;
for (GuiEventListener listener : widgets)
- if (listener != REIRuntimeImpl.getSearchField() && listener == getFocused() && listener.keyPressed(keyCode, scanCode, modifiers))
+ if (listener != REIRuntimeImpl.getSearchField() && listener == getFocused() && listener.keyReleased(keyCode, scanCode, modifiers))
return true;
}
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java
index bdb5a8168..8fe6cd45d 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java
@@ -90,7 +90,8 @@ public interface AllREIConfigGroups {
.add(COLLAPSIBLE_ENTRIES);
OptionGroup FAVORITES_FAVORITES = make("favorites.favorites")
.add(FAVORITES_MODE)
- .add(NEW_FAVORITES_BUTTON_VISIBILITY);
+ .add(NEW_FAVORITES_BUTTON_VISIBILITY)
+ .add(CALCULATOR_MODE);
OptionGroup FAVORITES_ADVANCED = make("favorites.advanced")
.add(GAME_MODE_COMMAND)
.add(TIME_COMMAND)
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java
index 30a673e38..f0bff705b 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java
@@ -222,6 +222,8 @@ public interface AllREIConfigOptions {
.enabledDisabled();
CompositeOption<FavoriteAddWidgetMode> NEW_FAVORITES_BUTTON_VISIBILITY = make("favorites.new_favorites_button_visibility", i -> i.advanced.layout.favoriteAddWidgetMode, (i, v) -> i.advanced.layout.favoriteAddWidgetMode = v)
.enumOptions();
+ CompositeOption<Boolean> CALCULATOR_MODE = make("favorites.calculator_mode", i -> i.advanced.layout.calculatorPanel, (i, v) -> i.advanced.layout.calculatorPanel = v)
+ .enabledDisabled();
CompositeOption<String> GAME_MODE_COMMAND = make("favorites.game_mode_command", i -> i.advanced.commands.gamemodeCommand, (i, v) -> i.advanced.commands.gamemodeCommand = v)
.string();
CompositeOption<String> TIME_COMMAND = make("favorites.time_command", i -> i.advanced.commands.timeCommand, (i, v) -> i.advanced.commands.timeCommand = v)
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java
index 63d2d8dd6..fed2d31a9 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java
@@ -55,7 +55,8 @@ import me.shedaniel.rei.impl.client.gui.widget.favorites.history.DisplayHistoryM
import me.shedaniel.rei.impl.client.gui.widget.favorites.history.DisplayHistoryWidget;
import me.shedaniel.rei.impl.client.gui.widget.favorites.listeners.FavoritesRegionListener;
import me.shedaniel.rei.impl.client.gui.widget.favorites.listeners.FavoritesSystemRegionListener;
-import me.shedaniel.rei.impl.client.gui.widget.favorites.panel.FavoritesPanel;
+import me.shedaniel.rei.impl.client.gui.widget.favorites.panel.CalculatorPanel;
+import me.shedaniel.rei.impl.client.gui.widget.favorites.panel.FavoritesAddPanel;
import me.shedaniel.rei.impl.client.gui.widget.favorites.panel.FavoritesTogglePanelButton;
import me.shedaniel.rei.impl.client.gui.widget.favorites.trash.TrashWidget;
import me.shedaniel.rei.impl.client.gui.widget.region.EntryStacksRegionWidget;
@@ -64,7 +65,6 @@ import me.shedaniel.rei.impl.client.gui.widget.region.RegionDraggableStack;
import me.shedaniel.rei.impl.common.util.RectangleUtils;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
-import net.minecraft.network.chat.Component;
import org.apache.commons.lang3.mutable.MutableLong;
import org.apache.commons.lang3.tuple.Triple;
import org.jetbrains.annotations.ApiStatus;
@@ -85,20 +85,13 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableCo
private EntryStacksRegionWidget<FavoriteEntry> region = new EntryStacksRegionWidget<>(new FavoritesRegionListener(this));
private List<FavoriteEntry> lastSystemEntries = new ArrayList<>();
- public final FavoritesPanel favoritePanel = new FavoritesPanel(this);
+ public final FavoritesAddPanel favoritePanel = new FavoritesAddPanel(this);
+ public final CalculatorPanel calculatorPanel = new CalculatorPanel(this);
public final TrashWidget trash = new TrashWidget(this);
public final DisplayHistoryWidget displayHistory = new DisplayHistoryWidget(this);
- public final FavoritesTogglePanelButton togglePanelButton = new FavoritesTogglePanelButton(this, 0, Component.translatable("text.rei.add_favorite_widget"),
- favoritePanel.expendState, () -> {
- favoritePanel.expendState.setTo(!favoritePanel.expendState.target(), ConfigObject.getInstance().isReducedMotion() ? 0 : 1500);
- favoritePanel.resetRows();
- });
- public final FavoritesTogglePanelButton calculatorPanelButton = new FavoritesTogglePanelButton(this, 1, Component.translatable("text.rei.calculator_widget"),
- favoritePanel.expendState, () -> {
- favoritePanel.expendState.setTo(!favoritePanel.expendState.target(), ConfigObject.getInstance().isReducedMotion() ? 0 : 1500);
- favoritePanel.resetRows();
- });
- private final List<Widget> children = ImmutableList.of(favoritePanel, togglePanelButton, calculatorPanelButton, systemRegion, region);
+ public final FavoritesTogglePanelButton togglePanelButton = new FavoritesTogglePanelButton.ToggleAdd(this);
+ public final FavoritesTogglePanelButton calculatorPanelButton = new FavoritesTogglePanelButton.ToggleCalculator(this);
+ private final List<Widget> children = ImmutableList.of(favoritePanel, calculatorPanel, togglePanelButton, calculatorPanelButton, systemRegion, region);
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double amountX, double amountY) {
@@ -213,12 +206,12 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableCo
displayHistory.render(graphics, mouseX, mouseY, delta);
- if (favoritePanel.getBounds().height > 20) {
- // Opened favorites panel
- region.getBounds().setBounds(this.favoritesBounds.x, this.favoritesBounds.y + topOffsetHeight, this.favoritesBounds.width, this.favoritesBounds.height - topOffsetHeight - (this.favoritesBounds.getMaxY() - this.favoritePanel.getBounds().y) - 4 - (Math.round(trashHeight) <= 0 ? 0 : trashHeight));
- } else {
- region.getBounds().setBounds(this.favoritesBounds.x, this.favoritesBounds.y + topOffsetHeight, this.favoritesBounds.width, this.favoritesBounds.height - topOffsetHeight - (Math.round(trashHeight) <= 0 ? 0 : trashHeight + 24));
- }
+ int removeExtraHeight = 0;
+
+ if (favoritePanel.getBounds().height > 20) removeExtraHeight += this.favoritesBounds.getMaxY() - this.favoritePanel.getBounds().y + 4;
+ if (calculatorPanel.getBounds().height > 20) removeExtraHeight += this.favoritesBounds.getMaxY() - this.calculatorPanel.getBounds().y + 4;
+
+ region.getBounds().setBounds(this.favoritesBounds.x, this.favoritesBounds.y + topOffsetHeight, this.favoritesBounds.width, this.favoritesBounds.height - topOffsetHeight - removeExtraHeight - (Math.round(trashHeight) <= 0 ? 0 : trashHeight));
systemRegion.render(graphics, mouseX, mouseY, delta);
region.render(graphics, mouseX, mouseY, delta);
@@ -269,6 +262,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableCo
private void renderAddFavorite(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
this.favoritePanel.render(graphics, mouseX, mouseY, delta);
+ this.calculatorPanel.render(graphics, mouseX, mouseY, delta);
this.togglePanelButton.render(graphics, mouseX, mouseY, delta);
this.calculatorPanelButton.render(graphics, mouseX, mouseY, delta);
}
@@ -324,4 +318,15 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableCo
return true;
return false;
}
+
+ @Override
+ public boolean charTyped(char character, int modifiers) {
+ if (containsMouse(mouse()))
+ for (Widget widget : children())
+ if (widget.charTyped(character, modifiers))
+ return true;
+ if (displayHistory.charTyped(character, modifiers))
+ return true;
+ return false;
+ }
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/CalculatorPanel.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/CalculatorPanel.java
new file mode 100644
index 000000000..17da10aff
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/CalculatorPanel.java
@@ -0,0 +1,124 @@
+package me.shedaniel.rei.impl.client.gui.widget.favorites.panel;
+
+import me.shedaniel.clothconfig2.api.animator.NumberAnimator;
+import me.shedaniel.clothconfig2.api.animator.ProgressValueAnimator;
+import me.shedaniel.clothconfig2.api.animator.ValueAnimator;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.config.ConfigObject;
+import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesListWidget;
+import me.shedaniel.rei.impl.client.gui.widget.search.CalculatorDisplayUtils;
+import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField;
+import me.shedaniel.rei.impl.client.gui.widget.search.TextCalculator;
+import me.shedaniel.rei.impl.client.util.ColorUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiGraphics;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.network.chat.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CalculatorPanel extends FavoritesPanel {
+ private final List<Row> rows = new ArrayList<>();
+ private final OverlaySearchField textField = new OverlaySearchField(0, 0, 0, 0, null);
+ private final NumberAnimator<Integer> previewHeight = ValueAnimator.ofDouble().asInt();
+ private CalculatorDisplayUtils utils = new CalculatorDisplayUtils(7);
+ private double eval;
+
+ public CalculatorPanel(FavoritesListWidget parent) {
+ super(parent);
+ this.textField.setHasBorder(false);
+ this.textField.isMain = false;
+ this.textField.setAutoPrefixEquals(true);
+ this.textField.setSuggestion(Component.empty());
+ this.textField.setResponder(text -> {
+ if (!text.isBlank() && TextCalculator.isValid('=' + text)) {
+ this.eval = new TextCalculator('=' + text).eval();
+ this.previewHeight.setTo(Minecraft.getInstance().font.lineHeight + 1, ConfigObject.getInstance().isReducedMotion() ? 0 : 400);
+ } else {
+ this.previewHeight.setTo(0, ConfigObject.getInstance().isReducedMotion() ? 0 : 400);
+ }
+ });
+ }
+
+ @Override
+ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
+ this.previewHeight.update(delta);
+ super.render(graphics, mouseX, mouseY, delta);
+ this.innerBounds.setBounds(bounds.x + 4, bounds.y + 4, bounds.width - 8, bounds.height - 8);
+
+ int previewLength = Math.max(7, (this.innerBounds.width - 4) / font.width("="));
+ if (previewLength != this.utils.maxLength()) this.utils = new CalculatorDisplayUtils(previewLength);
+
+ int buttonColor = 0xFFFFFF | (Math.round(0x34 * Math.min((float) expendState.progress() * 2, 1)) << 24);
+ graphics.fillGradient(bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), buttonColor, buttonColor);
+
+ if (expendState.progress() > 0.05f) {
+ Rectangle availableFullBounds = parent.favoritesBounds.clone();
+ availableFullBounds.height -= 20;
+ Rectangle scissorBounds = new Rectangle(innerBounds.x - 1, innerBounds.y - 1, innerBounds.width + 2, innerBounds.height + 2).intersection(availableFullBounds);
+ graphics.enableScissor(scissorBounds.x, scissorBounds.y, scissorBounds.getMaxX(), scissorBounds.getMaxY());
+ graphics.pose().pushPose();
+
+ // Text Field Background
+ Rectangle textFieldBorder = new Rectangle(innerBounds.x, innerBounds.getMaxY() - 9 - 5, innerBounds.width, 9 + 5);
+ boolean textFieldFocused = textFieldBorder.contains(mouseX, mouseY) || this.textField.isFocused();
+ int borderColor = ColorUtils.withAlpha(textFieldFocused ? 0x77FFFFFF : 0x77A0A0A0, expendState.progress());
+ int backgroundColor = ColorUtils.withAlpha(textFieldFocused ? 0xFF000000 : 0xC0000000, expendState.progress());
+ graphics.fillGradient(textFieldBorder.x - 1, textFieldBorder.y - 1, textFieldBorder.getMaxX() + 1, textFieldBorder.getMaxY() + 1, borderColor, borderColor);
+ graphics.fillGradient(textFieldBorder.x, textFieldBorder.y, textFieldBorder.getMaxX(), textFieldBorder.getMaxY(), backgroundColor, backgroundColor);
+ int leftPad = font.width("=");
+
+ // Equals
+ graphics.pose().pushPose();
+ graphics.pose().translate(-0.5, 0, 0);
+ graphics.drawString(font, "=", innerBounds.x + 2, innerBounds.getMaxY() - 9 - 2, ColorUtils.withAlpha(0xFFAAAAAA, expendState.progress()));
+ graphics.pose().popPose();
+
+ // Text Field
+ this.textField.getBounds().setBounds(innerBounds.x + 2 + leftPad, innerBounds.getMaxY() - 9 - 2, innerBounds.width - 4 - leftPad, 9);
+ this.textField.render(graphics, mouseX, mouseY, delta);
+
+ // Preview
+ if (this.previewHeight.value() > 0) {
+ int previewTop = textFieldBorder.y - 1 - this.previewHeight.value();
+ graphics.enableScissor(textFieldBorder.x - 1, previewTop, textFieldBorder.getMaxX() + 1, textFieldBorder.y - 1);
+ graphics.fillGradient(textFieldBorder.x - 1, previewTop, textFieldBorder.getMaxX() + 1, textFieldBorder.y - 1, borderColor, borderColor);
+ graphics.drawString(font, this.utils.fmt(this.eval), textFieldBorder.x + 2, previewTop + 2, 0xFF000000, false);
+ graphics.disableScissor();
+ }
+
+ graphics.pose().popPose();
+ graphics.disableScissor();
+ } else {
+ this.textField.getBounds().setBounds(0, 0, 0, 0);
+ }
+ }
+
+ @Override
+ protected Rectangle getButtonArea() {
+ return this.parent.calculatorPanelButton.getBounds();
+ }
+
+ @Override
+ protected Rectangle getTargetArea(Rectangle fullArea) {
+ return new Rectangle(
+ fullArea.x + 4,
+ fullArea.getMaxY() - 4 - 16 - fullArea.height * 0.4f,
+ fullArea.width - 8,
+ fullArea.height * 0.4f
+ );
+ }
+
+ @Override
+ public List<? extends GuiEventListener> children() {
+ return List.of(this.textField);
+ }
+
+ private record Row(String equation, double result, ProgressValueAnimator<Boolean> set) {
+ public Row(String equation, double result) {
+ this(equation, result, ValueAnimator.ofBoolean(false));
+ this.set().setTo(true, ConfigObject.getInstance().isReducedMotion() ? 0 : 500);
+ }
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FadingFavoritesPanelButton.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FadingFavoritesPanelButton.java
index 284d9fc0c..1297243fa 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FadingFavoritesPanelButton.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FadingFavoritesPanelButton.java
@@ -27,11 +27,11 @@ import me.shedaniel.clothconfig2.api.animator.NumberAnimator;
import me.shedaniel.clothconfig2.api.animator.ValueAnimator;
import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.api.client.config.ConfigObject;
+import me.shedaniel.rei.api.client.gui.config.FavoriteAddWidgetMode;
import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds;
import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesListWidget;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.events.GuiEventListener;
-import net.minecraft.client.renderer.MultiBufferSource;
import java.util.Collections;
import java.util.List;
@@ -51,8 +51,9 @@ public abstract class FadingFavoritesPanelButton extends WidgetWithBounds {
@Override
public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
this.bounds.setBounds(updateArea(parent.favoritesBounds));
- boolean hovered = containsMouse(mouseX, mouseY);
- switch (ConfigObject.getInstance().getFavoriteAddWidgetMode()) {
+ boolean hovered = containsMouse(mouseX, mouseY) & isVisible();
+ if (isOtherActive()) this.alpha.setTo(0, ConfigObject.getInstance().isReducedMotion() ? 0 : 750);
+ else switch (getFavoriteAddWidgetMode()) {
case ALWAYS_INVISIBLE:
this.alpha.setAs(0);
break;
@@ -60,7 +61,7 @@ public abstract class FadingFavoritesPanelButton extends WidgetWithBounds {
this.alpha.setTo(hovered ? 1f : isAvailable(mouseX, mouseY) ? 0.5f : 0f, ConfigObject.getInstance().isReducedMotion() ? 0 : 260);
break;
case ALWAYS_VISIBLE:
- this.alpha.setAs(hovered ? 1f : 0.5f);
+ this.alpha.setTo(hovered ? 1f : 0.5f, ConfigObject.getInstance().isReducedMotion() ? 0 : 750);
break;
}
this.alpha.update(delta);
@@ -74,6 +75,10 @@ public abstract class FadingFavoritesPanelButton extends WidgetWithBounds {
}
}
+ protected abstract boolean isOtherActive();
+
+ protected abstract FavoriteAddWidgetMode getFavoriteAddWidgetMode();
+
protected abstract boolean isAvailable(int mouseX, int mouseY);
protected abstract void renderContents(GuiGraphics graphics);
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FavoritesAddPanel.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FavoritesAddPanel.java
new file mode 100644
index 000000000..1f39b1d8a
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FavoritesAddPanel.java
@@ -0,0 +1,143 @@
+package me.shedaniel.rei.impl.client.gui.widget.favorites.panel;
+
+import me.shedaniel.clothconfig2.ClothConfigInitializer;
+import me.shedaniel.clothconfig2.api.LazyResettable;
+import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer;
+import me.shedaniel.math.Point;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.favorites.FavoriteEntry;
+import me.shedaniel.rei.api.client.favorites.FavoriteEntryType;
+import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponent;
+import me.shedaniel.rei.api.common.entry.EntryStack;
+import me.shedaniel.rei.api.common.util.CollectionUtils;
+import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesListWidget;
+import me.shedaniel.rei.impl.client.gui.widget.favorites.panel.rows.*;
+import net.minecraft.client.gui.GuiGraphics;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FavoritesAddPanel extends FavoritesPanel {
+ private final LazyResettable<List<FavoritesPanelRow>> rows = new LazyResettable<>(() -> {
+ List<FavoritesPanelRow> rows = new ArrayList<>();
+ for (FavoriteEntryType.Section section : FavoriteEntryType.registry().sections()) {
+ rows.add(new FavoritesPanelSectionRow(section.getText(), section.getText().copy().withStyle(style -> style.withUnderlined(true))));
+ rows.add(new FavoritesPanelEntriesRow(this, CollectionUtils.map(section.getEntries(), FavoriteEntry::copy)));
+ rows.add(new FavoritesPanelSeparatorRow());
+ }
+ if (!rows.isEmpty()) rows.remove(rows.size() - 1);
+ rows.add(new FavoritesPanelEmptyRow(4));
+ return rows;
+ });
+ private final ScrollingContainer scroller = new ScrollingContainer() {
+ @Override
+ public Rectangle getBounds() {
+ return innerBounds;
+ }
+
+ @Override
+ public int getMaxScrollHeight() {
+ return Math.max(1, rows.get().stream().mapToInt(FavoritesPanelRow::getRowHeight).sum());
+ }
+ };
+
+ public FavoritesAddPanel(FavoritesListWidget parent) {
+ super(parent);
+ }
+
+ public void resetRows() {
+ this.rows.reset();
+ }
+
+ @Override
+ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
+ super.render(graphics, mouseX, mouseY, delta);
+ this.innerBounds.setBounds(bounds.x + 4, bounds.y + 4, bounds.width - 8, bounds.height - 20);
+
+ int buttonColor = 0xFFFFFF | (Math.round(0x34 * Math.min((float) expendState.progress() * 2, 1)) << 24);
+ graphics.fillGradient(bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), buttonColor, buttonColor);
+ scroller.updatePosition(delta);
+
+ if (expendState.progress() > 0.05f) {
+ graphics.enableScissor(innerBounds.x, innerBounds.y, innerBounds.getMaxX(), innerBounds.getMaxY());
+ graphics.pose().pushPose();
+ graphics.pose().translate(0, -scroller.scrollAmount(), 0);
+ int y = innerBounds.y;
+ for (FavoritesPanelRow row : rows.get()) {
+ row.render(graphics, innerBounds, innerBounds.x, y, innerBounds.width, row.getRowHeight(), mouseX, mouseY + scroller.scrollAmountInt(), delta, (float) expendState.progress());
+ y += row.getRowHeight();
+ }
+ graphics.pose().popPose();
+ graphics.disableScissor();
+ }
+ }
+
+ @Override
+ protected Rectangle getButtonArea() {
+ return this.parent.togglePanelButton.getBounds();
+ }
+
+ @Override
+ protected Rectangle getTargetArea(Rectangle fullArea) {
+ return new Rectangle(
+ fullArea.x + 4,
+ fullArea.getMaxY() - 4 - fullArea.height * 0.4f,
+ fullArea.width - 8,
+ fullArea.height * 0.4f
+ );
+ }
+
+ @Override
+ public boolean mouseScrolled(double d, double e, double amountX, double amountY) {
+ if (innerBounds.contains(d, e) && amountY != 0) {
+ scroller.offset(ClothConfigInitializer.getScrollStep() * -amountY, true);
+ return true;
+ }
+ return super.mouseScrolled(d, e, amountX, amountY);
+ }
+
+ @Override
+ public List<? extends GuiEventListener> children() {
+ return rows.get();
+ }
+
+ public double getScrolledAmount() {
+ return scroller.scrollAmount();
+ }
+
+ public int getScrolledAmountInt() {
+ return scroller.scrollAmountInt();
+ }
+
+ @Nullable
+ public DraggableComponent<?> getHoveredStack(double mouseX, double mouseY) {
+ for (FavoritesPanelRow row : rows.get()) {
+ if (row instanceof FavoritesPanelEntriesRow entriesRow) {
+ DraggableComponent<?> hoveredStack = entriesRow.getHoveredStack(mouseX, mouseY);
+
+ if (hoveredStack != null) {
+ return hoveredStack;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Nullable
+ public EntryStack<?> getFocusedStack(Point mouse) {
+ for (FavoritesPanelRow row : rows.get()) {
+ if (row instanceof FavoritesPanelEntriesRow entriesRow) {
+ EntryStack<?> focusedStack = entriesRow.getFocusedStack(mouse);
+
+ if (focusedStack != null) {
+ return focusedStack;
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FavoritesPanel.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FavoritesPanel.java
index 3cd7be721..c0b868ee5 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FavoritesPanel.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/panel/FavoritesPanel.java
@@ -23,105 +23,39 @@
package me.shedaniel.rei.impl.client.gui.widget.favorites.panel;
-import me.shedaniel.clothconfig2.ClothConfigInitializer;
-import me.shedaniel.clothconfig2.api.LazyResettable;
import me.shedaniel.clothconfig2.api.animator.ProgressValueAnimator;
import me.shedaniel.clothconfig2.api.animator.ValueAnimator;
-import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer;
-import me.shedaniel.math.Point;
import me.shedaniel.math.Rectangle;
-import me.shedaniel.rei.api.client.favorites.FavoriteEntry;
-import me.shedaniel.rei.api.client.favorites.FavoriteEntryType;
-import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponent;
import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds;
-import me.shedaniel.rei.api.common.entry.EntryStack;
-import me.shedaniel.rei.api.common.util.CollectionUtils;
import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesListWidget;
-import me.shedaniel.rei.impl.client.gui.widget.favorites.panel.rows.*;
import net.minecraft.client.gui.GuiGraphics;
-import net.minecraft.client.gui.components.events.GuiEventListener;
-import org.jetbrains.annotations.Nullable;
+import net.minecraft.util.Mth;
-import java.util.ArrayList;
-import java.util.List;
-
-public class FavoritesPanel extends WidgetWithBounds {
- private final FavoritesListWidget parent;
+public abstract class FavoritesPanel extends WidgetWithBounds {
public final ProgressValueAnimator<Boolean> expendState = ValueAnimator.ofBoolean(0.1, false);
- private final Rectangle bounds = new Rectangle();
- private final Rectangle innerBounds = new Rectangle();
- private final LazyResettable<List<FavoritesPanelRow>> rows = new LazyResettable<>(() -> {
- List<FavoritesPanelRow> rows = new ArrayList<>();
- for (FavoriteEntryType.Section section : FavoriteEntryType.registry().sections()) {
- rows.add(new FavoritesPanelSectionRow(section.getText(), section.getText().copy().withStyle(style -> style.withUnderlined(true))));
- rows.add(new FavoritesPanelEntriesRow(this, CollectionUtils.map(section.getEntries(), FavoriteEntry::copy)));
- rows.add(new FavoritesPanelSeparatorRow());
- }
- if (!rows.isEmpty()) rows.remove(rows.size() - 1);
- rows.add(new FavoritesPanelEmptyRow(4));
- return ro