diff --git a/src/main/java/dan200/computercraft/client/gui/GuiComputer.java b/src/main/java/dan200/computercraft/client/gui/GuiComputer.java index 4996be560..57755785a 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiComputer.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiComputer.java @@ -7,8 +7,8 @@ import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.ComputerCraft; +import dan200.computercraft.client.gui.widgets.ComputerSidebar; import dan200.computercraft.client.gui.widgets.WidgetTerminal; -import dan200.computercraft.client.gui.widgets.WidgetWrapper; import dan200.computercraft.client.render.ComputerBorderRenderer; import dan200.computercraft.shared.computer.core.ClientComputer; import dan200.computercraft.shared.computer.core.ComputerFamily; @@ -17,12 +17,12 @@ import dan200.computercraft.shared.computer.inventory.ContainerViewComputer; import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer; import net.minecraft.client.gui.screen.inventory.ContainerScreen; +import net.minecraft.client.gui.widget.Widget; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.util.text.ITextComponent; import org.lwjgl.glfw.GLFW; import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER; -import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN; public final class GuiComputer extends ContainerScreen { @@ -31,8 +31,7 @@ public final class GuiComputer extends Containe private final int termWidth; private final int termHeight; - private WidgetTerminal terminal; - private WidgetWrapper terminalWrapper; + private WidgetTerminal terminal = null; private GuiComputer( T container, PlayerInventory player, ITextComponent title, int termWidth, int termHeight @@ -43,7 +42,9 @@ private GuiComputer( computer = (ClientComputer) container.getComputer(); this.termWidth = termWidth; this.termHeight = termHeight; - terminal = null; + + imageWidth = WidgetTerminal.getWidth( termWidth ) + BORDER * 2 + ComputerSidebar.WIDTH; + imageHeight = WidgetTerminal.getHeight( termHeight ) + BORDER * 2; } public static GuiComputer create( ContainerComputer container, PlayerInventory inventory, ITextComponent component ) @@ -74,29 +75,21 @@ public static GuiComputer createView( ContainerViewComput @Override protected void init() { - minecraft.keyboardHandler.setSendRepeatsToGui( true ); - - int termPxWidth = termWidth * FixedWidthFontRenderer.FONT_WIDTH; - int termPxHeight = termHeight * FixedWidthFontRenderer.FONT_HEIGHT; - - imageWidth = termPxWidth + MARGIN * 2 + BORDER * 2; - imageHeight = termPxHeight + MARGIN * 2 + BORDER * 2; - super.init(); - terminal = new WidgetTerminal( minecraft, () -> computer, termWidth, termHeight, MARGIN, MARGIN, MARGIN, MARGIN ); - terminalWrapper = new WidgetWrapper( terminal, MARGIN + BORDER + leftPos, MARGIN + BORDER + topPos, termPxWidth, termPxHeight ); + minecraft.keyboardHandler.setSendRepeatsToGui( true ); - children.add( terminalWrapper ); - setFocused( terminalWrapper ); + terminal = addButton( new WidgetTerminal( computer, + leftPos + ComputerSidebar.WIDTH + BORDER, topPos + BORDER, termWidth, termHeight + ) ); + ComputerSidebar.addButtons( this, computer, this::addButton, leftPos, topPos + BORDER ); + setFocused( terminal ); } @Override public void removed() { super.removed(); - children.remove( terminal ); - terminal = null; minecraft.keyboardHandler.setSendRepeatsToGui( false ); } @@ -111,7 +104,7 @@ public void tick() public boolean keyPressed( int key, int scancode, int modifiers ) { // Forward the tab key to the terminal, rather than moving between controls. - if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper ) + if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminal ) { return getFocused().keyPressed( key, scancode, modifiers ); } @@ -122,16 +115,11 @@ public boolean keyPressed( int key, int scancode, int modifiers ) @Override public void renderBg( float partialTicks, int mouseX, int mouseY ) { - // Draw terminal - terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() ); - // Draw a border around the terminal RenderSystem.color4f( 1, 1, 1, 1 ); minecraft.getTextureManager().bind( ComputerBorderRenderer.getTexture( family ) ); - ComputerBorderRenderer.render( - terminalWrapper.getX() - MARGIN, terminalWrapper.getY() - MARGIN, getBlitOffset(), - terminalWrapper.getWidth() + MARGIN * 2, terminalWrapper.getHeight() + MARGIN * 2 - ); + ComputerBorderRenderer.render( terminal.x, terminal.y, getBlitOffset(), terminal.getWidth(), terminal.getHeight() ); + ComputerSidebar.renderBackground( leftPos, topPos + BORDER ); } @Override @@ -140,6 +128,11 @@ public void render( int mouseX, int mouseY, float partialTicks ) renderBackground(); super.render( mouseX, mouseY, partialTicks ); renderTooltip( mouseX, mouseY ); + + for( Widget widget : buttons ) + { + if( widget.isHovered() ) widget.renderToolTip( mouseX, mouseY ); + } } @Override diff --git a/src/main/java/dan200/computercraft/client/gui/GuiTurtle.java b/src/main/java/dan200/computercraft/client/gui/GuiTurtle.java index 6af2a5790..ff24c6da0 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiTurtle.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiTurtle.java @@ -7,17 +7,21 @@ import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.ComputerCraft; +import dan200.computercraft.client.gui.widgets.ComputerSidebar; import dan200.computercraft.client.gui.widgets.WidgetTerminal; -import dan200.computercraft.client.gui.widgets.WidgetWrapper; +import dan200.computercraft.client.render.ComputerBorderRenderer; import dan200.computercraft.shared.computer.core.ClientComputer; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.turtle.inventory.ContainerTurtle; import net.minecraft.client.gui.screen.inventory.ContainerScreen; +import net.minecraft.client.gui.widget.Widget; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import org.lwjgl.glfw.GLFW; +import static dan200.computercraft.shared.turtle.inventory.ContainerTurtle.*; + public class GuiTurtle extends ContainerScreen { private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/turtle_normal.png" ); @@ -29,7 +33,6 @@ public class GuiTurtle extends ContainerScreen private final ClientComputer computer; private WidgetTerminal terminal; - private WidgetWrapper terminalWrapper; public GuiTurtle( ContainerTurtle container, PlayerInventory player, ITextComponent title ) { @@ -49,27 +52,18 @@ protected void init() super.init(); minecraft.keyboardHandler.setSendRepeatsToGui( true ); - int termPxWidth = ComputerCraft.turtleTermWidth * FixedWidthFontRenderer.FONT_WIDTH; - int termPxHeight = ComputerCraft.turtleTermHeight * FixedWidthFontRenderer.FONT_HEIGHT; - - terminal = new WidgetTerminal( - minecraft, () -> computer, - ComputerCraft.turtleTermWidth, - ComputerCraft.turtleTermHeight, - 2, 2, 2, 2 - ); - terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + leftPos, 2 + 8 + topPos, termPxWidth, termPxHeight ); - - children.add( terminalWrapper ); - setFocused( terminalWrapper ); + terminal = addButton( new WidgetTerminal( + computer, leftPos + BORDER + ComputerSidebar.WIDTH, topPos + BORDER, + ComputerCraft.turtleTermWidth, ComputerCraft.turtleTermHeight + ) ); + ComputerSidebar.addButtons( this, computer, this::addButton, leftPos, topPos + BORDER ); + setFocused( terminal ); } @Override public void removed() { super.removed(); - children.remove( terminal ); - terminal = null; minecraft.keyboardHandler.setSendRepeatsToGui( false ); } @@ -84,7 +78,7 @@ public void tick() public boolean keyPressed( int key, int scancode, int modifiers ) { // Forward the tab key to the terminal, rather than moving between controls. - if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper ) + if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminal ) { return getFocused().keyPressed( key, scancode, modifiers ); } @@ -92,41 +86,42 @@ public boolean keyPressed( int key, int scancode, int modifiers ) return super.keyPressed( key, scancode, modifiers ); } - private void drawSelectionSlot( boolean advanced ) + @Override + protected void renderBg( float partialTicks, int mouseX, int mouseY ) { - // Draw selection slot + boolean advanced = family == ComputerFamily.ADVANCED; + + RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); + minecraft.getTextureManager().bind( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL ); + blit( leftPos + ComputerSidebar.WIDTH, topPos, 0, 0, imageWidth, imageHeight ); + + minecraft.getTextureManager().bind( advanced ? ComputerBorderRenderer.BACKGROUND_ADVANCED : ComputerBorderRenderer.BACKGROUND_NORMAL ); + ComputerSidebar.renderBackground( leftPos, topPos + BORDER ); + int slot = container.getSelectedSlot(); if( slot >= 0 ) { RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); int slotX = slot % 4; int slotY = slot / 4; - minecraft.getTextureManager().bind( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL ); - blit( leftPos + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18, topPos + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18, 0, 217, 24, 24 ); + blit( + leftPos + TURTLE_START_X - 2 + slotX * 18, topPos + PLAYER_START_Y - 2 + slotY * 18, + 0, 217, 24, 24 + ); } } - @Override - protected void renderBg( float partialTicks, int mouseX, int mouseY ) - { - // Draw term - boolean advanced = family == ComputerFamily.ADVANCED; - terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() ); - - // Draw border/inventory - RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); - minecraft.getTextureManager().bind( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL ); - blit( leftPos, topPos, 0, 0, imageWidth, imageHeight ); - - drawSelectionSlot( advanced ); - } - @Override public void render( int mouseX, int mouseY, float partialTicks ) { renderBackground(); super.render( mouseX, mouseY, partialTicks ); renderTooltip( mouseX, mouseY ); + + for( Widget widget : buttons ) + { + if( widget.isHovered() ) widget.renderToolTip( mouseX, mouseY ); + } } @Override diff --git a/src/main/java/dan200/computercraft/client/gui/widgets/ComputerSidebar.java b/src/main/java/dan200/computercraft/client/gui/widgets/ComputerSidebar.java new file mode 100644 index 000000000..65cf1ae8a --- /dev/null +++ b/src/main/java/dan200/computercraft/client/gui/widgets/ComputerSidebar.java @@ -0,0 +1,105 @@ +/* + * This file is part of ComputerCraft - http://www.computercraft.info + * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission. + * Send enquiries to dratcliffe@gmail.com + */ +package dan200.computercraft.client.gui.widgets; + +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.client.render.ComputerBorderRenderer; +import dan200.computercraft.shared.computer.core.ClientComputer; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.client.resources.I18n; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextFormatting; + +import java.util.Arrays; +import java.util.function.Consumer; + +/** + * Registers buttons to interact with a computer. + */ +public final class ComputerSidebar +{ + private static final ResourceLocation TEXTURE = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/buttons.png" ); + + private static final int TEX_SIZE = 64; + + private static final int ICON_WIDTH = 12; + private static final int ICON_HEIGHT = 12; + private static final int ICON_MARGIN = 2; + + private static final int ICON_TEX_Y_DIFF = 14; + + private static final int CORNERS_BORDER = 3; + private static final int FULL_BORDER = CORNERS_BORDER + ICON_MARGIN; + + private static final int BUTTONS = 2; + private static final int HEIGHT = (ICON_HEIGHT + ICON_MARGIN * 2) * BUTTONS + CORNERS_BORDER * 2; + public static final int WIDTH = 17; + + private ComputerSidebar() + { + } + + public static void addButtons( Screen screen, ClientComputer computer, Consumer add, int x, int y ) + { + x += CORNERS_BORDER + 1; + y += CORNERS_BORDER + ICON_MARGIN; + + add.accept( new DynamicImageButton( + screen, x, y, ICON_WIDTH, ICON_HEIGHT, () -> computer.isOn() ? 15 : 1, 1, ICON_TEX_Y_DIFF, + TEXTURE, TEX_SIZE, TEX_SIZE, b -> toggleComputer( computer ), + () -> computer.isOn() ? Arrays.asList( + I18n.get( "gui.computercraft.tooltip.turn_off" ), + TextFormatting.GRAY + I18n.get( "gui.computercraft.tooltip.turn_off.key" ) + ) : Arrays.asList( + I18n.get( "gui.computercraft.tooltip.turn_on" ), + TextFormatting.GRAY + I18n.get( "gui.computercraft.tooltip.turn_off.key" ) + ) + ) ); + + y += ICON_HEIGHT + ICON_MARGIN * 2; + + add.accept( new DynamicImageButton( + screen, x, y, ICON_WIDTH, ICON_HEIGHT, 29, 1, ICON_TEX_Y_DIFF, + TEXTURE, TEX_SIZE, TEX_SIZE, b -> computer.queueEvent( "terminate" ), + Arrays.asList( + I18n.get( "gui.computercraft.tooltip.terminate" ), + TextFormatting.GRAY + I18n.get( "gui.computercraft.tooltip.terminate.key" ) + ) + ) ); + } + + public static void renderBackground( int x, int y ) + { + Screen.blit( + x, y, 0, 102, WIDTH, FULL_BORDER, + ComputerBorderRenderer.TEX_SIZE, ComputerBorderRenderer.TEX_SIZE + ); + + Screen.blit( + x, y + FULL_BORDER, WIDTH, HEIGHT - FULL_BORDER * 2, + 0, 107, WIDTH, 4, + ComputerBorderRenderer.TEX_SIZE, ComputerBorderRenderer.TEX_SIZE + ); + + Screen.blit( + x, y + HEIGHT - FULL_BORDER, 0, 111, WIDTH, FULL_BORDER, + ComputerBorderRenderer.TEX_SIZE, ComputerBorderRenderer.TEX_SIZE + ); + } + + private static void toggleComputer( ClientComputer computer ) + { + if( computer.isOn() ) + { + computer.shutdown(); + } + else + { + computer.turnOn(); + } + } +} diff --git a/src/main/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java b/src/main/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java new file mode 100644 index 000000000..af21d9e93 --- /dev/null +++ b/src/main/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java @@ -0,0 +1,92 @@ +/* + * This file is part of ComputerCraft - http://www.computercraft.info + * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission. + * Send enquiries to dratcliffe@gmail.com + */ +package dan200.computercraft.client.gui.widgets; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.button.Button; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.util.NonNullSupplier; + +import javax.annotation.Nonnull; +import java.util.List; +import java.util.function.IntSupplier; + +/** + * Version of {@link net.minecraft.client.gui.widget.button.ImageButton} which allows changing some properties + * dynamically. + */ +public class DynamicImageButton extends Button +{ + private final Screen screen; + private final ResourceLocation texture; + private final IntSupplier xTexStart; + private final int yTexStart; + private final int yDiffTex; + private final int textureWidth; + private final int textureHeight; + private final NonNullSupplier> tooltip; + + public DynamicImageButton( + Screen screen, int x, int y, int width, int height, int xTexStart, int yTexStart, int yDiffTex, + ResourceLocation texture, int textureWidth, int textureHeight, + IPressable onPress, List tooltip + ) + { + this( + screen, x, y, width, height, () -> xTexStart, yTexStart, yDiffTex, + texture, textureWidth, textureHeight, + onPress, () -> tooltip + ); + } + + + public DynamicImageButton( + Screen screen, int x, int y, int width, int height, IntSupplier xTexStart, int yTexStart, int yDiffTex, + ResourceLocation texture, int textureWidth, int textureHeight, + IPressable onPress, NonNullSupplier> tooltip + ) + { + super( x, y, width, height, "", onPress ); + this.screen = screen; + this.textureWidth = textureWidth; + this.textureHeight = textureHeight; + this.xTexStart = xTexStart; + this.yTexStart = yTexStart; + this.yDiffTex = yDiffTex; + this.texture = texture; + this.tooltip = tooltip; + } + + public void renderButton( int mouseX, int mouseY, float partialTicks ) + { + Minecraft minecraft = Minecraft.getInstance(); + minecraft.getTextureManager().bind( texture ); + RenderSystem.disableDepthTest(); + + int yTex = yTexStart; + if( isHovered() ) yTex += yDiffTex; + + blit( x, y, xTexStart.getAsInt(), yTex, width, height, textureWidth, textureHeight ); + RenderSystem.enableDepthTest(); + } + + @Nonnull + @Override + public String getMessage() + { + List tooltip = this.tooltip.get(); + return tooltip.isEmpty() ? "" : tooltip.get( 0 ); + } + + @Override + public void renderToolTip( int mouseX, int mouseY ) + { + List tooltip = this.tooltip.get(); + if( !tooltip.isEmpty() ) screen.renderTooltip( tooltip, mouseX, mouseY ); + } +} diff --git a/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java b/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java index 343e5229e..747654545 100644 --- a/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java +++ b/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java @@ -8,29 +8,29 @@ import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.computer.core.ClientComputer; -import dan200.computercraft.shared.computer.core.IComputer; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.IGuiEventListener; +import net.minecraft.client.gui.widget.Widget; import net.minecraft.util.SharedConstants; import org.lwjgl.glfw.GLFW; +import javax.annotation.Nonnull; import java.util.BitSet; -import java.util.function.Supplier; import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; +import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN; -public class WidgetTerminal implements IGuiEventListener +public class WidgetTerminal extends Widget { private static final float TERMINATE_TIME = 0.5f; - private final Minecraft client; + private final ClientComputer computer; - private boolean focused; - - private final Supplier computer; - private final int termWidth; - private final int termHeight; + // The positions of the actual terminal + private final int innerX; + private final int innerY; + private final int innerWidth; + private final int innerHeight; private float terminateTimer = -1; private float rebootTimer = -1; @@ -40,23 +40,18 @@ public class WidgetTerminal implements IGuiEventListener private int lastMouseX = -1; private int lastMouseY = -1; - private final int leftMargin; - private final int rightMargin; - private final int topMargin; - private final int bottomMargin; - private final BitSet keysDown = new BitSet( 256 ); - public WidgetTerminal( Minecraft client, Supplier computer, int termWidth, int termHeight, int leftMargin, int rightMargin, int topMargin, int bottomMargin ) + public WidgetTerminal( @Nonnull ClientComputer computer, int x, int y, int termWidth, int termHeight ) { - this.client = client; + super( x, y, termWidth * FONT_WIDTH + MARGIN * 2, termHeight * FONT_HEIGHT + MARGIN * 2, "" ); + this.computer = computer; - this.termWidth = termWidth; - this.termHeight = termHeight; - this.leftMargin = leftMargin; - this.rightMargin = rightMargin; - this.topMargin = topMargin; - this.bottomMargin = bottomMargin; + + innerX = x + MARGIN; + innerY = y + MARGIN; + innerWidth = termWidth * FONT_WIDTH; + innerHeight = termHeight * FONT_HEIGHT; } @Override @@ -65,7 +60,7 @@ public boolean charTyped( char ch, int modifiers ) if( ch >= 32 && ch <= 126 || ch >= 160 && ch <= 255 ) // printable chars in byte range { // Queue the "char" event - queueEvent( "char", Character.toString( ch ) ); + computer.queueEvent( "char", new Object[] { Character.toString( ch ) } ); } return true; @@ -91,7 +86,7 @@ public boolean keyPressed( int key, int scancode, int modifiers ) case GLFW.GLFW_KEY_V: // Ctrl+V for paste - String clipboard = client.keyboardHandler.getClipboard(); + String clipboard = Minecraft.getInstance().keyboardHandler.getClipboard(); if( clipboard != null ) { // Clip to the first occurrence of \r or \n @@ -116,7 +111,7 @@ else if( newLineIndex2 >= 0 ) { // Clip to 512 characters and queue the event if( clipboard.length() > 512 ) clipboard = clipboard.substring( 0, 512 ); - queueEvent( "paste", clipboard ); + computer.queueEvent( "paste", new Object[] { clipboard } ); } return true; @@ -129,8 +124,7 @@ else if( newLineIndex2 >= 0 ) // Queue the "key" event and add to the down set boolean repeat = keysDown.get( key ); keysDown.set( key ); - IComputer computer = this.computer.get(); - if( computer != null ) computer.keyDown( key, repeat ); + computer.keyDown( key, repeat ); } return true; @@ -143,8 +137,7 @@ public boolean keyReleased( int key, int scancode, int modifiers ) if( key >= 0 && keysDown.get( key ) ) { keysDown.set( key, false ); - IComputer computer = this.computer.get(); - if( computer != null ) computer.keyUp( key ); + computer.keyUp( key ); } switch( key ) @@ -170,14 +163,14 @@ public boolean keyReleased( int key, int scancode, int modifiers ) @Override public boolean mouseClicked( double mouseX, double mouseY, int button ) { - ClientComputer computer = this.computer.get(); - if( computer == null || !computer.isColour() || button < 0 || button > 2 ) return false; + if( !inTermRegion( mouseX, mouseY ) ) return false; + if( !computer.isColour() || button < 0 || button > 2 ) return false; Terminal term = computer.getTerminal(); if( term != null ) { - int charX = (int) (mouseX / FONT_WIDTH); - int charY = (int) (mouseY / FONT_HEIGHT); + int charX = (int) ((mouseX - x) / FONT_WIDTH); + int charY = (int) ((mouseY - x) / FONT_HEIGHT); charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 ); charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 ); @@ -194,14 +187,14 @@ public boolean mouseClicked( double mouseX, double mouseY, int button ) @Override public boolean mouseReleased( double mouseX, double mouseY, int button ) { - ClientComputer computer = this.computer.get(); - if( computer == null || !computer.isColour() || button < 0 || button > 2 ) return false; + if( !inTermRegion( mouseX, mouseY ) ) return false; + if( !computer.isColour() || button < 0 || button > 2 ) return false; Terminal term = computer.getTerminal(); if( term != null ) { - int charX = (int) (mouseX / FONT_WIDTH); - int charY = (int) (mouseY / FONT_HEIGHT); + int charX = (int) ((mouseX - x) / FONT_WIDTH); + int charY = (int) ((mouseY - x) / FONT_HEIGHT); charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 ); charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 ); @@ -221,14 +214,14 @@ public boolean mouseReleased( double mouseX, double mouseY, int button ) @Override public boolean mouseDragged( double mouseX, double mouseY, int button, double v2, double v3 ) { - ClientComputer computer = this.computer.get(); - if( computer == null || !computer.isColour() || button < 0 || button > 2 ) return false; + if( !inTermRegion( mouseX, mouseY ) ) return false; + if( !computer.isColour() || button < 0 || button > 2 ) return false; Terminal term = computer.getTerminal(); if( term != null ) { - int charX = (int) (mouseX / FONT_WIDTH); - int charY = (int) (mouseY / FONT_HEIGHT); + int charX = (int) ((mouseX - x) / FONT_WIDTH); + int charY = (int) ((mouseY - x) / FONT_HEIGHT); charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 ); charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 ); @@ -246,14 +239,14 @@ public boolean mouseDragged( double mouseX, double mouseY, int button, double v2 @Override public boolean mouseScrolled( double mouseX, double mouseY, double delta ) { - ClientComputer computer = this.computer.get(); - if( computer == null || !computer.isColour() || delta == 0 ) return false; + if( !inTermRegion( mouseX, mouseY ) ) return false; + if( !computer.isColour() || delta == 0 ) return false; Terminal term = computer.getTerminal(); if( term != null ) { - int charX = (int) (mouseX / FONT_WIDTH); - int charY = (int) (mouseY / FONT_HEIGHT); + int charX = (int) ((mouseX - innerX) / FONT_WIDTH); + int charY = (int) ((mouseY - innerY) / FONT_HEIGHT); charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 ); charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 ); @@ -266,84 +259,64 @@ public boolean mouseScrolled( double mouseX, double mouseY, double delta ) return true; } + private boolean inTermRegion( double mouseX, double mouseY ) + { + return active && visible && mouseX >= innerX && mouseY >= innerY && mouseX < innerX + innerWidth && mouseY < innerY + innerHeight; + } + public void update() { if( terminateTimer >= 0 && terminateTimer < TERMINATE_TIME && (terminateTimer += 0.05f) > TERMINATE_TIME ) { - queueEvent( "terminate" ); + computer.queueEvent( "terminate" ); } if( shutdownTimer >= 0 && shutdownTimer < TERMINATE_TIME && (shutdownTimer += 0.05f) > TERMINATE_TIME ) { - ClientComputer computer = this.computer.get(); - if( computer != null ) computer.shutdown(); + computer.shutdown(); } if( rebootTimer >= 0 && rebootTimer < TERMINATE_TIME && (rebootTimer += 0.05f) > TERMINATE_TIME ) { - ClientComputer computer = this.computer.get(); - if( computer != null ) computer.reboot(); + computer.reboot(); } } @Override - public boolean changeFocus( boolean reversed ) + public void onFocusedChanged( boolean focused ) { - if( focused ) + if( !focused ) { // When blurring, we should make all keys go up for( int key = 0; key < keysDown.size(); key++ ) { - if( keysDown.get( key ) ) queueEvent( "key_up", key ); + if( keysDown.get( key ) ) computer.keyUp( key ); } keysDown.clear(); // When blurring, we should make the last mouse button go up if( lastMouseButton > 0 ) { - IComputer computer = this.computer.get(); - if( computer != null ) computer.mouseUp( lastMouseButton + 1, lastMouseX + 1, lastMouseY + 1 ); + computer.mouseUp( lastMouseButton + 1, lastMouseX + 1, lastMouseY + 1 ); lastMouseButton = -1; } shutdownTimer = terminateTimer = rebootTimer = -1; } - focused = !focused; - return true; } - public void draw( int originX, int originY ) + public void render( int mouseX, int mouseY, float partialTicks ) { - synchronized( computer ) + // Draw the screen contents + Terminal terminal = computer.getTerminal(); + if( terminal != null ) { - // Draw the screen contents - ClientComputer computer = this.computer.get(); - Terminal terminal = computer != null ? computer.getTerminal() : null; - if( terminal != null ) - { - FixedWidthFontRenderer.drawTerminal( originX, originY, terminal, !computer.isColour(), topMargin, bottomMargin, leftMargin, rightMargin ); - } - else - { - FixedWidthFontRenderer.drawEmptyTerminal( - originX - leftMargin, originY - rightMargin, - termWidth * FONT_WIDTH + leftMargin + rightMargin, - termHeight * FONT_HEIGHT + topMargin + bottomMargin - ); - } + FixedWidthFontRenderer.drawTerminal( innerX, innerY, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN ); + } + else + { + FixedWidthFontRenderer.drawEmptyTerminal( x, y, width, height ); } - } - - private void queueEvent( String event ) - { - ClientComputer computer = this.computer.get(); - if( computer != null ) computer.queueEvent( event ); - } - - private void queueEvent( String event, Object... args ) - { - ClientComputer computer = this.computer.get(); - if( computer != null ) computer.queueEvent( event, args ); } @Override @@ -351,4 +324,14 @@ public boolean isMouseOver( double x, double y ) { return true; } + + public static int getWidth( int termWidth ) + { + return termWidth * FONT_WIDTH + MARGIN * 2; + } + + public static int getHeight( int termHeight ) + { + return termHeight * FONT_HEIGHT + MARGIN * 2; + } } diff --git a/src/main/java/dan200/computercraft/client/gui/widgets/WidgetWrapper.java b/src/main/java/dan200/computercraft/client/gui/widgets/WidgetWrapper.java deleted file mode 100644 index 45ca4617e..000000000 --- a/src/main/java/dan200/computercraft/client/gui/widgets/WidgetWrapper.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of ComputerCraft - http://www.computercraft.info - * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission. - * Send enquiries to dratcliffe@gmail.com - */ -package dan200.computercraft.client.gui.widgets; - -import net.minecraft.client.gui.IGuiEventListener; - -public class WidgetWrapper implements IGuiEventListener -{ - private final IGuiEventListener listener; - private final int x; - private final int y; - private final int width; - private final int height; - - public WidgetWrapper( IGuiEventListener listener, int x, int y, int width, int height ) - { - this.listener = listener; - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } - - @Override - public boolean changeFocus( boolean b ) - { - return listener.changeFocus( b ); - } - - @Override - public boolean mouseClicked( double x, double y, int button ) - { - double dx = x - this.x, dy = y - this.y; - return dx >= 0 && dx < width && dy >= 0 && dy < height && listener.mouseClicked( dx, dy, button ); - } - - @Override - public boolean mouseReleased( double x, double y, int button ) - { - double dx = x - this.x, dy = y - this.y; - return dx >= 0 && dx < width && dy >= 0 && dy < height && listener.mouseReleased( dx, dy, button ); - } - - @Override - public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY ) - { - double dx = x - this.x, dy = y - this.y; - return dx >= 0 && dx < width && dy >= 0 && dy < height && listener.mouseDragged( dx, dy, button, deltaX, deltaY ); - } - - @Override - public boolean mouseScrolled( double x, double y, double delta ) - { - double dx = x - this.x, dy = y - this.y; - return dx >= 0 && dx < width && dy >= 0 && dy < height && listener.mouseScrolled( dx, dy, delta ); - } - - @Override - public boolean keyPressed( int key, int scancode, int modifiers ) - { - return listener.keyPressed( key, scancode, modifiers ); - } - - @Override - public boolean keyReleased( int key, int scancode, int modifiers ) - { - return listener.keyReleased( key, scancode, modifiers ); - } - - @Override - public boolean charTyped( char character, int modifiers ) - { - return listener.charTyped( character, modifiers ); - } - - public int getX() - { - return x; - } - - public int getY() - { - return y; - } - - public int getWidth() - { - return width; - } - - public int getHeight() - { - return height; - } - - @Override - public boolean isMouseOver( double x, double y ) - { - double dx = x - this.x, dy = y - this.y; - return dx >= 0 && dx < width && dy >= 0 && dy < height; - } -} diff --git a/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java b/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java index bd52458f3..bd6c047c6 100644 --- a/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java @@ -52,7 +52,8 @@ public class ComputerBorderRenderer public static final int LIGHT_HEIGHT = 8; - private static final float TEX_SCALE = 1 / 256.0f; + public static final int TEX_SIZE = 256; + private static final float TEX_SCALE = 1 / (float) TEX_SIZE; private final Matrix4f transform; private final IVertexBuilder builder; diff --git a/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java index c11357614..fffa5ea26 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java @@ -5,6 +5,7 @@ */ package dan200.computercraft.shared.turtle.inventory; +import dan200.computercraft.client.gui.widgets.ComputerSidebar; import dan200.computercraft.shared.Registry; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.IComputer; @@ -27,8 +28,10 @@ public class ContainerTurtle extends ContainerComputerBase { + public static final int BORDER = 8; public static final int PLAYER_START_Y = 134; - public static final int TURTLE_START_X = 175; + public static final int TURTLE_START_X = ComputerSidebar.WIDTH + 175; + public static final int PLAYER_START_X = ComputerSidebar.WIDTH + BORDER; private final IIntArray properties; @@ -56,14 +59,14 @@ private ContainerTurtle( { for( int x = 0; x < 9; x++ ) { - addSlot( new Slot( playerInventory, x + y * 9 + 9, 8 + x * 18, PLAYER_START_Y + 1 + y * 18 ) ); + addSlot( new Slot( playerInventory, x + y * 9 + 9, PLAYER_START_X + x * 18, PLAYER_START_Y + 1 + y * 18 ) ); } } // Player hotbar for( int x = 0; x < 9; x++ ) { - addSlot( new Slot( playerInventory, x, 8 + x * 18, PLAYER_START_Y + 3 * 18 + 5 ) ); + addSlot( new Slot( playerInventory, x, PLAYER_START_X + x * 18, PLAYER_START_Y + 3 * 18 + 5 ) ); } } diff --git a/src/main/resources/assets/computercraft/lang/en_us.json b/src/main/resources/assets/computercraft/lang/en_us.json index f97fc40d7..755148279 100644 --- a/src/main/resources/assets/computercraft/lang/en_us.json +++ b/src/main/resources/assets/computercraft/lang/en_us.json @@ -110,5 +110,11 @@ "tracking_field.computercraft.coroutines_dead.name": "Coroutines disposed", "gui.computercraft.tooltip.copy": "Copy to clipboard", "gui.computercraft.tooltip.computer_id": "Computer ID: %s", - "gui.computercraft.tooltip.disk_id": "Disk ID: %s" + "gui.computercraft.tooltip.disk_id": "Disk ID: %s", + "gui.computercraft.tooltip.turn_on": "Turn this computer on", + "gui.computercraft.tooltip.turn_on.key": "Hold Ctrl+R", + "gui.computercraft.tooltip.turn_off": "Turn this computer off", + "gui.computercraft.tooltip.turn_off.key": "Hold Ctrl+S", + "gui.computercraft.tooltip.terminate": "Stop the currently running code", + "gui.computercraft.tooltip.terminate.key": "Hold Ctrl+T" } diff --git a/src/main/resources/assets/computercraft/textures/gui/buttons.png b/src/main/resources/assets/computercraft/textures/gui/buttons.png new file mode 100644 index 000000000..69ef550ee Binary files /dev/null and b/src/main/resources/assets/computercraft/textures/gui/buttons.png differ diff --git a/src/main/resources/assets/computercraft/textures/gui/corners_advanced.png b/src/main/resources/assets/computercraft/textures/gui/corners_advanced.png index d42b9e4fd..a53ae0715 100644 Binary files a/src/main/resources/assets/computercraft/textures/gui/corners_advanced.png and b/src/main/resources/assets/computercraft/textures/gui/corners_advanced.png differ diff --git a/src/main/resources/assets/computercraft/textures/gui/corners_normal.png b/src/main/resources/assets/computercraft/textures/gui/corners_normal.png index 8b1e9f676..0532a5289 100644 Binary files a/src/main/resources/assets/computercraft/textures/gui/corners_normal.png and b/src/main/resources/assets/computercraft/textures/gui/corners_normal.png differ