aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky/skyblocker/skyblock/quicknav/QuickNavButton.java
blob: 75c25e587643ef30bf6b620a55749792646407d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package de.hysky.skyblocker.skyblock.quicknav;

import com.mojang.blaze3d.systems.RenderSystem;
import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor;
import de.hysky.skyblocker.utils.scheduler.MessageScheduler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;

@Environment(value = EnvType.CLIENT)
public class QuickNavButton extends ClickableWidget {
    private final int index;
    private final boolean toggled;
    private boolean temporaryToggled = false;
    private final String command;
    private final ItemStack icon;

    private static final long TOGGLE_DURATION = 1000;
    private long toggleTime;

    private float alpha = 1.0f;

    /**
     * Checks if the current tab is a top tab based on its index.
     *
     * @return true if the index is less than 7, false otherwise.
     */
    private boolean isTopTab() {
        return index < 7;
    }

    public boolean toggled() {
        return toggled || temporaryToggled;
    }

    /**
     * Constructs a new QuickNavButton with the given parameters.
     *
     * @param index   the index of the button.
     * @param toggled the toggled state of the button.
     * @param command the command to execute when the button is clicked.
     * @param icon    the icon to display on the button.
     */
    public QuickNavButton(int index, boolean toggled, String command, ItemStack icon) {
        super(0, 0, 26, 32, Text.empty());
        this.index = index;
        this.toggled = toggled;
        this.command = command;
        this.icon = icon;
        this.toggleTime = 0;
    }

    private void updateCoordinates() {
        Screen screen = MinecraftClient.getInstance().currentScreen;
        if (screen instanceof HandledScreen<?> handledScreen) {
            int x = ((HandledScreenAccessor) handledScreen).getX();
            int y = ((HandledScreenAccessor) handledScreen).getY();
            int h = ((HandledScreenAccessor) handledScreen).getBackgroundHeight();
            this.setX(x + this.index % 7 * 25);
            this.setY(this.index < 7 ? y - 28 : y + h - 4);
        }
    }

    /**
     * Handles click events. If the button is not currently toggled,
     * it sets the toggled state to true and sends a message with the command after cooldown.
     *
     * @param mouseX the x-coordinate of the mouse click
     * @param mouseY the y-coordinate of the mouse click
     */
    @Override
    public void onClick(double mouseX, double mouseY) {
        if (!this.temporaryToggled) {
            this.temporaryToggled = true;
            this.toggleTime = System.currentTimeMillis();
            MessageScheduler.INSTANCE.sendMessageAfterCooldown(command);
            // TODO : add null check with log error
            this.alpha = 0.5f;
        }
    }

    /**
     * Renders the button on screen. This includes both its texture and its icon.
     * The method first updates the coordinates of the button,
     * then calculates appropriate values for rendering based on its current state,
     * and finally draws both the background and icon of the button on screen.
     *
     * @param context the context in which to render the button
     * @param mouseX  the x-coordinate of the mouse cursor
     * @param mouseY  the y-coordinate of the mouse cursor
     */
    @Override
    public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
        this.updateCoordinates();
        RenderSystem.disableDepthTest();

        if (this.temporaryToggled && System.currentTimeMillis() - this.toggleTime >= TOGGLE_DURATION) {
            this.temporaryToggled = false; // Reset toggled state
        }
        //"animation"
        if (this.alpha < 1.0f) {
            this.alpha += 0.05f;
            if (this.alpha > 1.0f) {
                this.alpha = 1.0f;
            }
        }

        //"animation"
        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();
        RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, this.alpha);

        // Construct the texture identifier based on the index and toggled state
        Identifier tabTexture = Identifier.ofVanilla("container/creative_inventory/tab_" + (isTopTab() ? "top" : "bottom") + "_" + (toggled() ? "selected" : "unselected") + "_" + (index % 7 + 1));

        // Render the button texture
        context.drawGuiTexture(tabTexture, this.getX(), this.getY(), this.width, this.height);
        // Render the button icon
        int yOffset = this.index < 7 ? 1 : -1;
        context.drawItem(this.icon, this.getX() + 5, this.getY() + 8 + yOffset);
        //prevent "fading animation" on not quicknav stuff
        RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
        RenderSystem.disableBlend();

        RenderSystem.enableDepthTest();
    }

    @Override
    protected void appendClickableNarrations(NarrationMessageBuilder builder) {}
}