• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CyclopsMC / IntegratedDynamics / 15141775592

20 May 2025 03:33PM UTC coverage: 45.542% (+0.001%) from 45.541%
15141775592

push

github

rubensworks
Merge remote-tracking branch 'origin/master-1.21-lts' into master-1.21

2558 of 8407 branches covered (30.43%)

Branch coverage included in aggregate %.

11878 of 23291 relevant lines covered (51.0%)

2.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/java/org/cyclops/integrateddynamics/client/gui/container/ContainerScreenLogicProgrammerBase.java
1
package org.cyclops.integrateddynamics.client.gui.container;
2

3
import com.google.common.collect.Lists;
4
import com.mojang.blaze3d.platform.InputConstants;
5
import net.minecraft.client.gui.Font;
6
import net.minecraft.client.gui.GuiGraphics;
7
import net.minecraft.client.renderer.RenderType;
8
import net.minecraft.client.renderer.texture.TextureManager;
9
import net.minecraft.network.chat.Component;
10
import net.minecraft.resources.ResourceLocation;
11
import net.minecraft.util.ARGB;
12
import net.minecraft.world.entity.player.Inventory;
13
import net.minecraft.world.item.ItemStack;
14
import org.apache.commons.lang3.tuple.Triple;
15
import org.cyclops.cyclopscore.client.gui.component.button.ButtonText;
16
import org.cyclops.cyclopscore.client.gui.component.input.WidgetTextFieldExtended;
17
import org.cyclops.cyclopscore.client.gui.container.ContainerScreenScrolling;
18
import org.cyclops.cyclopscore.helper.IModHelpers;
19
import org.cyclops.integrateddynamics.IntegratedDynamics;
20
import org.cyclops.integrateddynamics.Reference;
21
import org.cyclops.integrateddynamics.RegistryEntries;
22
import org.cyclops.integrateddynamics.api.client.gui.subgui.IGuiInputElement;
23
import org.cyclops.integrateddynamics.api.logicprogrammer.ILogicProgrammerElement;
24
import org.cyclops.integrateddynamics.api.logicprogrammer.ILogicProgrammerElementType;
25
import org.cyclops.integrateddynamics.core.client.gui.subgui.SubGuiHolder;
26
import org.cyclops.integrateddynamics.core.evaluate.variable.gui.GuiElementValueTypeString;
27
import org.cyclops.integrateddynamics.core.helper.L10NValues;
28
import org.cyclops.integrateddynamics.core.logicprogrammer.LogicProgrammerElementTypes;
29
import org.cyclops.integrateddynamics.core.logicprogrammer.RenderPattern;
30
import org.cyclops.integrateddynamics.inventory.container.ContainerLogicProgrammerBase;
31
import org.cyclops.integrateddynamics.network.packet.LogicProgrammerActivateElementPacket;
32
import org.cyclops.integrateddynamics.network.packet.LogicProgrammerLabelPacket;
33
import org.cyclops.integrateddynamics.proxy.ClientProxy;
34
import org.lwjgl.glfw.GLFW;
35

36
import java.awt.*;
37
import java.util.List;
38

39
/**
40
 * Base gui for the logic programmer.
41
 * @author rubensworks
42
 */
43
public class ContainerScreenLogicProgrammerBase<C extends ContainerLogicProgrammerBase> extends ContainerScreenScrolling<C> {
44

45
    public static final int BOX_HEIGHT = 18;
46
    private static final Rectangle ITEM_POSITION = new Rectangle(19, 18, 56, BOX_HEIGHT - 1);
×
47

48
    protected final SubGuiHolder subGuiHolder = new SubGuiHolder();
×
49
    private final boolean hasLabeller;
50
    protected RenderPattern operatorConfigPattern = null;
×
51
    protected SubGuiOperatorInfo operatorInfoPattern = null;
×
52
    protected boolean firstInit = true;
×
53
    protected int relativeStep = -1;
×
54
    protected boolean swallowNextCharacter = false;
×
55

56
    public ContainerScreenLogicProgrammerBase(C container, Inventory playerInventory, Component title) {
57
        super(container, playerInventory, title);
×
58
        container.setGui(this);
×
59

60
        this.hasLabeller = playerInventory.contains(new ItemStack(RegistryEntries.ITEM_LABELLER));
×
61
    }
×
62

63
    @Override
64
    protected Rectangle getScrollRegion() {
65
        return new Rectangle(this.leftPos + 19, this.topPos + 18, 57, 178);
×
66
    }
67

68
    @Override
69
    public void init() {
70
        super.init();
×
71
        subGuiHolder.init(this.leftPos, this.topPos);
×
72
        if (firstInit) {
×
73
            setSearchFieldFocussed(true);
×
74
            firstInit = false;
×
75
        }
76
    }
×
77

78
    @Override
79
    public void containerTick() {
80
        super.containerTick();
×
81
        subGuiHolder.tick();
×
82
    }
×
83

84
    protected int getScrollX() {
85
        return 5;
×
86
    }
87

88
    protected int getScrollY() {
89
        return 18;
×
90
    }
91

92
    protected int getScrollHeight() {
93
        return 178;
×
94
    }
95

96
    @Override
97
    protected int getBaseXSize() {
98
        return 256;
×
99
    }
100

101
    @Override
102
    protected int getBaseYSize() {
103
        return 240;
×
104
    }
105

106
    @Override
107
    protected int getSearchX() {
108
        return 6;
×
109
    }
110

111
    protected int getSearchWidth() {
112
        return 70;
×
113
    }
114

115
    @Override
116
    protected ResourceLocation constructGuiTexture() {
117
        return ResourceLocation.fromNamespaceAndPath(Reference.MOD_ID, "textures/gui/logic_programmer.png");
×
118
    }
119

120
    protected float colorSmoothener(float color, boolean hover) {
121
        return 1F - ((1F - color) / (hover ? 2F : 4F));
×
122
    }
123

124
    @Override
125
    protected void renderBg(GuiGraphics guiGraphics, float partialTicks, int mouseX, int mouseY) {
126
        super.renderBg(guiGraphics, partialTicks, mouseX, mouseY);
×
127
        subGuiHolder.renderBg(guiGraphics, this.leftPos, this.topPos, getMinecraft().getTextureManager(), font, partialTicks, mouseX, mouseY);
×
128

129
        // Draw container name
130
        guiGraphics.drawString(font, Component.translatable(L10NValues.GUI_LOGICPROGRAMMER_FILTER),
×
131
                this.leftPos + offsetX + 5, this.topPos + offsetY + 208, IModHelpers.get().getBaseHelpers().RGBToInt(80, 80, 80),
×
132
                false);
133

134
        // Draw operators
135
        ContainerLogicProgrammerBase container = (ContainerLogicProgrammerBase) getMenu();
×
136
        int boxHeight = BOX_HEIGHT;
×
137
        for(int i = 0; i < container.getPageSize(); i++) {
×
138
            if(container.isElementVisible(i)) {
×
139
                ILogicProgrammerElement element = container.getVisibleElement(i);
×
140

141
                Triple<Float, Float, Float> rgb = IModHelpers.get().getBaseHelpers().intToRGB(element.getColor());
×
142
                boolean hover = LogicProgrammerElementTypes.areEqual(container.getActiveElement(), element)
×
143
                        || isPointInRegion(getElementPosition(container, i, false), new Point(mouseX, mouseY));
×
144
                int color = ARGB.colorFromFloat(
×
145
                        1F,
146
                        colorSmoothener(rgb.getLeft(), hover),
×
147
                        colorSmoothener(rgb.getMiddle(), hover),
×
148
                        colorSmoothener(rgb.getRight(), hover)
×
149
                );
150

151
                // Background
152
                guiGraphics.blit(RenderType::guiTextured, texture, leftPos + offsetX + ITEM_POSITION.x,
×
153
                        topPos + offsetY + ITEM_POSITION.y + boxHeight * i, 19, 18, ITEM_POSITION.width, ITEM_POSITION.height, 256, 256, color);
154

155
                // Arrow
156
                if(hover) {
×
157
                    guiGraphics.blit(RenderType::guiTextured, texture, leftPos + offsetX + ITEM_POSITION.x,
×
158
                            topPos + offsetY + ITEM_POSITION.y + boxHeight * i, 0, 240, 3, 16, 256, 256, color);
159
                }
160

161
                // Operator info
162
                String aspectName = element.getSymbol();
×
163
                IModHelpers.get().getRenderHelpers().drawScaledCenteredString(guiGraphics, font, aspectName,
×
164
                        this.leftPos + offsetX + (hover ? 22 : 21),
×
165
                        this.topPos + offsetY + 26 + boxHeight * i,
166
                        53, IModHelpers.get().getBaseHelpers().RGBToInt(40, 40, 40), false, Font.DisplayMode.NORMAL);
×
167
            }
168
        }
169
    }
×
170

171
    protected Rectangle getElementPosition(ContainerLogicProgrammerBase container, int i, boolean absolute) {
172
        return new Rectangle(ITEM_POSITION.x + offsetX + (absolute ? this.leftPos : 0),
×
173
                ITEM_POSITION.y + BOX_HEIGHT * i + offsetY + (absolute ? this.topPos : 0),
×
174
                ITEM_POSITION.width, ITEM_POSITION.height
175
        );
176
    }
177

178
    @Override
179
    protected void renderLabels(GuiGraphics guiGraphics, int mouseX, int mouseY) {
180
        // super.drawGuiContainerForegroundLayer(matrixStack, mouseX, mouseY);
181
        subGuiHolder.drawGuiContainerForegroundLayer(guiGraphics, this.leftPos, this.topPos, getMinecraft().getTextureManager(), font, mouseX, mouseY);
×
182
        // Draw operator tooltips
183
        ContainerLogicProgrammerBase container = getMenu();
×
184
        for(int i = 0; i < container.getPageSize(); i++) {
×
185
            if(container.isElementVisible(i)) {
×
186
                ILogicProgrammerElement element = container.getVisibleElement(i);
×
187
                if(isPointInRegion(getElementPosition(container, i, false), new Point(mouseX, mouseY))) {
×
188
                    List<Component> lines = Lists.newLinkedList();
×
189
                    element.loadTooltip(lines);
×
190
                    drawTooltip(lines, guiGraphics.pose(), mouseX - this.leftPos, mouseY - this.topPos);
×
191
                }
192
            }
193
        }
194
    }
×
195

196
    protected void onActivateElement(ILogicProgrammerElement<RenderPattern, ContainerScreenLogicProgrammerBase<?>, ContainerLogicProgrammerBase> element) {
197
        subGuiHolder.addSubGui(operatorInfoPattern = new SubGuiOperatorInfo(element));
×
198
        operatorInfoPattern.init(leftPos, topPos);
×
199
        subGuiHolder.addSubGui(operatorConfigPattern = element.createSubGui(88, 18, 160, 87, this, (ContainerLogicProgrammerBase) getMenu()));
×
200
        operatorConfigPattern.init(leftPos, topPos);
×
201
    }
×
202

203
    protected void onDeactivateElement(ILogicProgrammerElement element) {
204
        subGuiHolder.clear();
×
205
    }
×
206

207
    public boolean handleElementActivation(ILogicProgrammerElement element) {
208
        boolean activate = false;
×
209
        ContainerLogicProgrammerBase container = getMenu();
×
210
        ILogicProgrammerElement newActive = null;
×
211
        onDeactivateElement(element);
×
212
        if(container.getActiveElement() != element) {
×
213
            activate = true;
×
214
            newActive = element;
×
215
            if(element != null) {
×
216
                onActivateElement(element);
×
217
            }
218
        }
219
        container.setActiveElement(newActive,
×
220
                operatorConfigPattern == null ? 0 : operatorConfigPattern.getX(),
×
221
                operatorConfigPattern == null ? 0 : operatorConfigPattern.getY());
×
222
        if(newActive != null) {
×
223
            ILogicProgrammerElementType type = newActive.getType();
×
224
            IntegratedDynamics._instance.getPacketHandler().sendToServer(
×
225
                    new LogicProgrammerActivateElementPacket(type.getUniqueName(), type.getName(newActive)));
×
226
        } else {
×
227
            IntegratedDynamics._instance.getPacketHandler().sendToServer(
×
228
                    new LogicProgrammerActivateElementPacket(ResourceLocation.parse(""), ResourceLocation.parse("")));
×
229
        }
230
        return activate;
×
231
    }
232

233
    protected void setSearchFieldFocussed(boolean focused) {
234
        getSearchField().setFocused(focused);
×
235
    }
×
236

237
    protected boolean isSearchFieldFocussed() {
238
        return getSearchField().isFocused();
×
239
    }
240

241
    protected boolean selectPageElement(int elementId) {
242
        ContainerLogicProgrammerBase container = getMenu();
×
243

244
        // Deactivate current element
245
        if (elementId < 0) {
×
246
            handleElementActivation(container.getActiveElement());
×
247
            return false;
×
248
        }
249

250
        // Activate a new element
251
        for(int i = 0; i < container.getPageSize(); i++) {
×
252
            if (container.isElementVisible(i)) {
×
253
                if (elementId-- == 0) {
×
254
                    ILogicProgrammerElement element = container.getVisibleElement(i);
×
255
                    if (container.getActiveElement() != element) {
×
256
                        handleElementActivation(element);
×
257
                    }
258
                    return true;
×
259
                }
260
            }
261
        }
262
        return false;
×
263
    }
264

265
    protected boolean handleKeyCode(int keyCode, int scanCode) {
266
        InputConstants.Key inputCode = InputConstants.getKey(keyCode, scanCode);
×
267
        if(keyCode != GLFW.GLFW_KEY_LEFT_SHIFT && keyCode != GLFW.GLFW_KEY_RIGHT_SHIFT) {
×
268
            ContainerLogicProgrammerBase container = getMenu();
×
269
            int pageSize = container.getPageSize();
×
270
            int stepModifier = IModHelpers.get().getMinecraftClientHelpers().isShifted() ? pageSize - 1 : 1;
×
271
            boolean isElementFocused = container.getActiveElement() != null && container.getActiveElement().isFocused(operatorConfigPattern);
×
272

273
            if (ClientProxy.FOCUS_LP_SEARCH.isActiveAndMatches(inputCode)) {
×
274
                // Focus search field
275
                setSearchFieldFocussed(true);
×
276
                swallowNextCharacter = true;
×
277
                return true;
×
278
            } else if (isElementFocused && ClientProxy.FOCUS_LP_RENAME.isActiveAndMatches(inputCode) && hasLabeller()) {
×
279
                // Open labeller gui
280
                operatorInfoPattern.onButtonEditClick();
×
281
                swallowNextCharacter = true;
×
282
                return true;
×
283
            } else if (GLFW.GLFW_KEY_LEFT == keyCode && (!isElementFocused && isSearchFieldFocussed())) {
×
284
                // Unfocus search field
285
                setSearchFieldFocussed(isSearchFieldFocussed());
×
286
                return true;
×
287
            } else if (!isElementFocused && GLFW.GLFW_KEY_DOWN == keyCode) {
×
288
                // Scroll down
289
                if (!selectPageElement(relativeStep += stepModifier)) {
×
290
                    relativeStep -= stepModifier;
×
291
                    if (relativeStep > 0) {
×
292
                        getScrollbar().scrollRelative(-stepModifier);
×
293
                        selectPageElement(relativeStep);
×
294
                    }
295
                }
296
                return true;
×
297
            } else if (!isElementFocused && GLFW.GLFW_KEY_UP == keyCode) {
×
298
                // Scroll up
299
                if (!(relativeStep >= 0 && selectPageElement(relativeStep -= stepModifier))) {
×
300
                    getScrollbar().scrollRelative(stepModifier);
×
301
                    selectPageElement(relativeStep = 0);
×
302
                }
303
                return true;
×
304
            } else if (!isElementFocused
×
305
                    && (GLFW.GLFW_KEY_RIGHT == keyCode || GLFW.GLFW_KEY_TAB == keyCode
306
                    || GLFW.GLFW_KEY_ENTER == keyCode || GLFW.GLFW_KEY_KP_ENTER == keyCode)) {
307
                if (container.getActiveElement() != null) {
×
308
                    container.getActiveElement().setFocused(operatorConfigPattern, true);
×
309
                    setSearchFieldFocussed(false);
×
310
                }
311
                return true;
×
312
            }
313
        }
314
        return false;
×
315
    }
316

317
    @Override
318
    public boolean charTyped(char keyCode, int scanCode) {
319
        if (swallowNextCharacter) {
×
320
            swallowNextCharacter = false;
×
321
            return true;
×
322
        }
323

324
        return subGuiHolder.charTyped(keyCode, scanCode) || handleKeyCode(keyCode, scanCode) || super.charTyped(keyCode, scanCode);
×
325
    }
326

327
    @Override
328
    public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
329
        if (keyCode != GLFW.GLFW_KEY_ESCAPE) {
×
330
            if (this.subGuiHolder.keyPressed(keyCode, scanCode, modifiers) || handleKeyCode(keyCode, scanCode)) {
×
331
                return true;
×
332
            }
333
        }
334
        return super.keyPressed(keyCode, scanCode, modifiers);
×
335
    }
336

337
    @Override
338
    public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
339
        if (subGuiHolder.mouseClicked(mouseX, mouseY, mouseButton)) {
×
340
            if (isSearchFieldFocussed()) {
×
341
                setSearchFieldFocussed(false);
×
342
            }
343
            return true;
×
344
        }
345

346
        ContainerLogicProgrammerBase container = getMenu();
×
347
        for(int i = 0; i < container.getPageSize(); i++) {
×
348
            if (container.isElementVisible(i)) {
×
349
                ILogicProgrammerElement element = container.getVisibleElement(i);
×
350
                if (isPointInRegion(getElementPosition(container, i, false), new Point((int) mouseX, (int) mouseY))) {
×
351
                    boolean activated = handleElementActivation(element);
×
352
                    relativeStep = activated ? i : -1;
×
353
                    if (activated) {
×
354
                        container.getActiveElement().setFocused(operatorConfigPattern, true);
×
355
                        setSearchFieldFocussed(false);
×
356
                        return true;
×
357
                    }
358
                }
359
            }
360
        }
361
        boolean superRet = super.mouseClicked(mouseX, mouseY, mouseButton);
×
362

363
        // If the search box has been selected, de-active the current element.
364
        if(isSearchFieldFocussed() &&
×
365
                container.getActiveElement() != null && container.getActiveElement().isFocused(operatorConfigPattern)) {
×
366
            container.getActiveElement().setFocused(operatorConfigPattern, false);
×
367
            return true;
×
368
        }
369

370
        return superRet;
×
371
    }
372

373
    protected void label(String label) {
374
        IntegratedDynamics._instance.getPacketHandler().sendToServer(new LogicProgrammerLabelPacket(label));
×
375
    }
×
376

377
    protected boolean hasLabeller() {
378
        return this.hasLabeller;
×
379
    }
380

381
    public class SubGuiOperatorInfo extends GuiElementValueTypeString.SubGuiValueTypeInfo<RenderPattern, ContainerScreenLogicProgrammerBase<?>, ContainerLogicProgrammerBase> {
382

383
        private WidgetTextFieldExtended searchField;
384
        private ButtonText button = null;
×
385

386
        public SubGuiOperatorInfo(IGuiInputElement<RenderPattern, ContainerScreenLogicProgrammerBase<?>, ContainerLogicProgrammerBase> element) {
×
387
            super(ContainerScreenLogicProgrammerBase.this, getMenu(), element, 88, 106, 139, 20);
×
388

389
            if(hasLabeller()) {
×
390
                buttonList.add(button = new ButtonText(0, 0, 6, 10, Component.translatable("gui.integrateddynamics.button.edit"), Component.literal("E"),
×
391
                        (button) -> onButtonEditClick(), true));
×
392
            }
393

394
            int searchWidth = 113;
×
395
            this.searchField = new WidgetTextFieldExtended(ContainerScreenLogicProgrammerBase.this.font, 0, 0, searchWidth, 11,
×
396
                    Component.translatable("gui.cyclopscore.search"));
×
397
            this.searchField.setMaxLength(64);
×
398
            this.searchField.setBordered(true);
×
399
            this.searchField.setVisible(false);
×
400
            this.searchField.setTextColor(16777215);
×
401
            this.searchField.setCanLoseFocus(true);
×
402
            this.searchField.setValue("");
×
403
            this.searchField.setWidth(searchWidth);
×
404
        }
×
405

406
        @Override
407
        public void init(int guiLeft, int guiTop) {
408
            super.init(guiLeft, guiTop);
×
409
            int searchX = 90;
×
410
            int searchY = 110;
×
411
            this.searchField.setX(guiLeft + searchX);
×
412
            this.searchField.setY(guiTop + searchY);
×
413

414
            if (hasLabeller()) {
×
415
                button.setX(guiLeft + 220);
×
416
                button.setY(guiTop + 111);
×
417
            }
418
        }
×
419

420
        @Override
421
        protected boolean showError() {
422
            return container.canWriteActiveElementPre();
×
423
        }
424

425
        @Override
426
        protected Component getLastError() {
427
            return container.getLastError();
×
428
        }
429

430
        @Override
431
        protected ResourceLocation getTexture() {
432
            return texture;
×
433
        }
434

435
        @Override
436
        public boolean charTyped(char typedChar, int keyCode) {
437
            if (!this.searchField.isFocused() || !this.searchField.charTyped(typedChar, keyCode)) {
×
438
                return super.charTyped(typedChar, keyCode);
×
439
            } else {
440
                label(this.searchField.getValue());
×
441
                return true;
×
442
            }
443
        }
444

445
        @Override
446
        public boolean keyPressed(int typedChar, int keyCode, int modifiers) {
447
            if (this.searchField.isFocused() && typedChar != GLFW.GLFW_KEY_ESCAPE) {
×
448
                this.searchField.keyPressed(typedChar, keyCode, modifiers);
×
449
                label(this.searchField.getValue());
×
450
                return true;
×
451
            }
452
            return super.keyPressed(typedChar, keyCode, modifiers);
×
453
        }
454

455
        @Override
456
        public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
457
            if(this.searchField.isVisible() && this.searchField.mouseClicked(mouseX, mouseY, mouseButton)) {
×
458
                return true;
×
459
            }
460
            return super.mouseClicked(mouseX, mouseY, mouseButton);
×
461
        }
462

463
        @Override
464
        public void renderBg(GuiGraphics guiGraphics, int guiLeft, int guiTop, TextureManager textureManager, Font font, float partialTicks, int mouseX, int mouseY) {
465
            super.renderBg(guiGraphics, guiLeft, guiTop, textureManager, font, partialTicks, mouseX, mouseY);
×
466
            this.searchField.render(guiGraphics, mouseX, mouseY, partialTicks);
×
467
        }
×
468

469
        @Override
470
        public boolean shouldRenderElementName() {
471
            return !this.searchField.isVisible();
×
472
        }
473

474
        public void onButtonEditClick() {
475
            this.searchField.setVisible(!this.searchField.isVisible());
×
476
            if(this.searchField.isVisible()) {
×
477
                this.searchField.setFocused(true);
×
478
                label(this.searchField.getValue());
×
479
            } else {
480
                label("");
×
481
            }
482
        }
×
483
    }
484

485
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc