aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/cc/polyfrost/oneconfig/hud/Hud.java
blob: 62cfb2ea1428deb151d36cf83d059d1970f2dadc (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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
package cc.polyfrost.oneconfig.hud;

import cc.polyfrost.oneconfig.config.annotations.Switch;
import cc.polyfrost.oneconfig.config.core.OneColor;
import cc.polyfrost.oneconfig.gui.OneConfigGui;
import cc.polyfrost.oneconfig.libs.universal.UMinecraft;
import cc.polyfrost.oneconfig.libs.universal.UScreen;
import cc.polyfrost.oneconfig.renderer.RenderManager;
import cc.polyfrost.oneconfig.config.Config;
import net.minecraft.client.gui.GuiChat;

/**
 * Represents a HUD element in OneConfig.
 * A HUD element can be used to display useful information to the user, like FPS or CPS.
 * <p>
 * If you simply want to display text, extend {@link TextHud} or {@link SingleTextHud},
 * whichever applies to the use case. Then, override the required methods.
 * <p>
 * If you want to display something else, extend this class and override {@link Hud#getWidth(float)}, {@link Hud#getHeight(float)}, and {@link Hud#draw(int, int, float)} with the width, height, and the drawing code respectively.
 * </p>
 * <p>
 * It should also be noted that additional options to the HUD can be added simply by declaring them.
 * <pre>{@code
 *     public class TestHud extends SingleTextHud {
 *         @literal @Switch(
 *             name = "Additional Option"
 *         )
 *         public boolean additionalOption = true;
 *     }
 *     }</pre>
 * </p>
 * To register an element, add it to your OneConfig {@link Config}.
 * <pre>{@code
 *  *     public class YourConfig extends Config {
 *  *         @literal @HUD(
 *  *             name = "HUD Element"
 *  *         )
 *  *         public YourHudElement hudElement = new YourHudElement("Title");
 *  *     }
 *  *     }</pre>
 */
public abstract class Hud {
    public boolean enabled;
    public boolean rounded;
    public boolean border;
    public OneColor bgColor;
    public OneColor borderColor;
    public float cornerRadius;
    public float borderSize;
    public double xUnscaled;
    public double yUnscaled;
    public float scale;
    public float paddingX;
    public float paddingY;

    /**
     * @param enabled      If the hud is enabled
     * @param x            X-coordinate of hud on a 1080p display
     * @param y            Y-coordinate of hud on a 1080p display
     * @param scale        Scale of the hud
     * @param rounded      If the corner is rounded or not
     * @param cornerRadius Radius of the corner
     * @param paddingX     Horizontal background padding
     * @param paddingY     Vertical background padding
     * @param bgColor      Background color
     * @param border       If the hud has a border or not
     * @param borderSize   Thickness of the border
     * @param borderColor  The color of the border
     */
    public Hud(boolean enabled, int x, int y, float scale, boolean rounded, int cornerRadius, int paddingX, int paddingY, OneColor bgColor, boolean border, float borderSize, OneColor borderColor) {
        this.enabled = enabled;
        this.scale = scale;
        this.rounded = rounded;
        this.cornerRadius = cornerRadius;
        this.paddingX = paddingX;
        this.paddingY = paddingY;
        this.bgColor = bgColor;
        this.border = border;
        this.borderSize = borderSize;
        this.borderColor = borderColor;
        if (x / 1920d <= 0.5d) xUnscaled = x / 1920d;
        else xUnscaled = (x + getWidth(scale)) / 1920d;
        if (y / 1080d <= 0.5d) yUnscaled = y / 1080d;
        else yUnscaled = (y + getHeight(scale)) / 1090d;
    }

    /**
     * @param enabled If the hud is enabled
     * @param x       X-coordinate of hud on a 1080p display
     * @param y       Y-coordinate of hud on a 1080p display
     * @param scale   Scale of the hud
     */
    public Hud(boolean enabled, int x, int y, int scale) {
        this(enabled, x, y, scale, false, 2, 5, 5, new OneColor(0, 0, 0, 120), false, 2, new OneColor(0, 0, 0));
    }

    /**
     * @param enabled If the hud is enabled
     * @param x       X-coordinate of hud on a 1080p display
     * @param y       Y-coordinate of hud on a 1080p display
     */
    public Hud(boolean enabled, int x, int y) {
        this(enabled, x, y, 1, false, 2, 5, 5, new OneColor(0, 0, 0, 120), false, 2, new OneColor(0, 0, 0));
    }

    /**
     * @param enabled If the hud is enabled
     */
    public Hud(boolean enabled) {
        this(enabled, 0, 0, 1, false, 2, 5, 5, new OneColor(0, 0, 0, 120), false, 2, new OneColor(0, 0, 0));
    }

    /**
     * Function called when drawing the hud
     *
     * @param x     Top left x-coordinate of the hud
     * @param y     Top left y-coordinate of the hud
     * @param scale Scale of the hud
     */
    public abstract void draw(int x, int y, float scale);

    /**
     * Function called when drawing the example version of the hud.
     * This is used in for example, the hud editor gui.
     *
     * @param x     Top left x-coordinate of the hud
     * @param y     Top left y-coordinate of the hud
     * @param scale Scale of the hud
     */
    public void drawExample(int x, int y, float scale) {
        draw(x, y, scale);
    }

    /**
     * @param scale Scale of the hud
     * @return The width of the hud
     */
    public abstract int getWidth(float scale);

    /**
     * @param scale Scale of the hud
     * @return The height of the hud
     */
    public abstract int getHeight(float scale);

    /**
     * @param scale Scale of the hud
     * @return The width of the example version of the hud
     */
    public int getExampleWidth(float scale) {
        return getWidth(scale);
    }

    /**
     * @param scale Scale of the hud
     * @return The height of the example version of the hud
     */
    public int getExampleHeight(float scale) {
        return getHeight(scale);
    }

    /**
     * @return If the background should be drawn
     */
    public boolean drawBackground() {
        return true;
    }

    /**
     * Draw the background, the hud and all childed huds, used by HudCore
     *
     * @param x          X-coordinate
     * @param y          Y-coordinate
     * @param scale      Scale of the hud
     * @param background If background should be drawn or not
     */
    public void drawAll(float x, float y, float scale, boolean background) {
        if (!showInGuis && UScreen.getCurrentScreen() != null && !(UScreen.getCurrentScreen() instanceof OneConfigGui)) return;
        if (!showInChat && UScreen.getCurrentScreen() instanceof GuiChat) return;
        if (!showInDebug && UMinecraft.getSettings().showDebugInfo) return;
        if (background && drawBackground()) drawBackground(x, y, getWidth(scale), getHeight(scale), scale);
        draw((int) (x + paddingX * scale / 2f), (int) (y + paddingY * scale / 2f), scale);
    }

    /**
     * Draw example version of the background, the hud and all childed huds, used by HudGui
     *
     * @param x          X-coordinate
     * @param y          Y-coordinate
     * @param scale      Scale of the hud
     * @param background If background should be drawn or not
     */
    public void drawExampleAll(float x, float y, float scale, boolean background) {
        if (background) drawBackground(x, y, getWidth(scale), getHeight(scale), scale);
        drawExample((int) (x + paddingX * scale / 2f), (int) (y + paddingY * scale / 2f), scale);
    }

    /**
     * Draw example version of the background, the hud and all childed huds, used by HudGui
     *
     * @param x      X-coordinate
     * @param y      Y-coordinate
     * @param width  Width of the hud
     * @param height Height of the hud
     * @param scale  Scale of the hud
     */
    private void drawBackground(float x, float y, float width, float height, float scale) {
        RenderManager.setupAndDraw(true, (vg) -> {
            if (rounded) {
                RenderManager.drawRoundedRect(vg, x, y, (width + paddingX * scale), (height + paddingY * scale), bgColor.getRGB(), cornerRadius * scale);
                if (border)
                    RenderManager.drawHollowRoundRect(vg, x - borderSize * scale, y - borderSize * scale, (width + paddingX * scale) + borderSize * scale, (height + paddingY * scale) + borderSize * scale, borderColor.getRGB(), cornerRadius * scale, borderSize * scale);
            } else {
                RenderManager.drawRect(vg, x, y, (width + paddingX * scale), (height + paddingY * scale), bgColor.getRGB());
                if (border)
                    RenderManager.drawHollowRoundRect(vg, x - borderSize * scale, y - borderSize * scale, (width + paddingX * scale) + borderSize * scale, (height + paddingY * scale) + borderSize * scale, borderColor.getRGB(), 0, borderSize * scale);
            }
        });
    }

    /**
     * @param screenWidth width of the screen
     * @return X-coordinate of the hud
     */
    public float getXScaled(int screenWidth) {
        if (xUnscaled <= 0.5)
            return (int) (screenWidth * xUnscaled);
        return (float) (screenWidth - (1d - xUnscaled) * screenWidth - (getWidth(scale) + paddingX * scale));
    }

    /**
     * @param screenHeight height of the screen
     * @return Y-coordinate of the hud
     */
    public float getYScaled(int screenHeight) {
        if (yUnscaled <= 0.5) return (int) (screenHeight * yUnscaled);
        return (float) (screenHeight - (1d - yUnscaled) * screenHeight - (getHeight(scale) + paddingY * scale));
    }

    @Switch(
            name = "Show in Chat"
    )
    public boolean showInChat = true;

    @Switch(
            name = "Show in F3 (Debug)"
    )
    public boolean showInDebug = false;

    @Switch(
            name = "Show in GUIs"
    )
    public boolean showInGuis = true;
}