1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-12-04 05:18:05 +00:00

Started work on upgrading to 1.16.1. Not in a compilable state yet

This commit is contained in:
Alex Evelyn
2020-07-07 13:27:13 -04:00
parent cb66ef7e30
commit 605e1f6b9b
513 changed files with 48117 additions and 534 deletions

View File

@@ -0,0 +1,200 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.util.Identifier;
import org.lwjgl.opengl.GL11;
import java.util.Arrays;
public final class FixedWidthFontRenderer
{
private static final Identifier FONT = new Identifier( "computercraft", "textures/gui/term_font.png" );
public static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/term_background.png" );
public static final int FONT_HEIGHT = 9;
public static final int FONT_WIDTH = 6;
private static FixedWidthFontRenderer instance;
public static FixedWidthFontRenderer instance()
{
if( instance != null ) return instance;
return instance = new FixedWidthFontRenderer();
}
private final TextureManager m_textureManager;
private FixedWidthFontRenderer()
{
m_textureManager = MinecraftClient.getInstance().getTextureManager();
}
private static void greyscaleify( double[] rgb )
{
Arrays.fill( rgb, (rgb[0] + rgb[1] + rgb[2]) / 3.0f );
}
private void drawChar( BufferBuilder renderer, double x, double y, int index, int color, Palette p, boolean greyscale )
{
int column = index % 16;
int row = index / 16;
double[] colour = p.getColour( 15 - color );
if( greyscale )
{
greyscaleify( colour );
}
float r = (float) colour[0];
float g = (float) colour[1];
float b = (float) colour[2];
int xStart = 1 + column * (FONT_WIDTH + 2);
int yStart = 1 + row * (FONT_HEIGHT + 2);
renderer.vertex( x, y, 0.0 ).texture( xStart / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).next();
renderer.vertex( x, y + FONT_HEIGHT, 0.0 ).texture( xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).next();
renderer.vertex( x + FONT_WIDTH, y, 0.0 ).texture( (xStart + FONT_WIDTH) / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).next();
renderer.vertex( x + FONT_WIDTH, y, 0.0 ).texture( (xStart + FONT_WIDTH) / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).next();
renderer.vertex( x, y + FONT_HEIGHT, 0.0 ).texture( xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).next();
renderer.vertex( x + FONT_WIDTH, y + FONT_HEIGHT, 0.0 ).texture( (xStart + FONT_WIDTH) / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).next();
}
private void drawQuad( BufferBuilder renderer, double x, double y, int color, double width, Palette p, boolean greyscale )
{
double[] colour = p.getColour( 15 - color );
if( greyscale )
{
greyscaleify( colour );
}
float r = (float) colour[0];
float g = (float) colour[1];
float b = (float) colour[2];
renderer.vertex( x, y, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.vertex( x, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.vertex( x + width, y, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.vertex( x + width, y, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.vertex( x, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).next();
renderer.vertex( x + width, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).next();
}
private boolean isGreyScale( int colour )
{
return colour == 0 || colour == 15 || colour == 7 || colour == 8;
}
public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )
{
// Draw the quads
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder renderer = tessellator.getBuffer();
renderer.begin( GL11.GL_TRIANGLES, VertexFormats.POSITION_COLOR );
if( leftMarginSize > 0.0 )
{
int colour1 = "0123456789abcdef".indexOf( backgroundColour.charAt( 0 ) );
if( colour1 < 0 || (greyScale && !isGreyScale( colour1 )) )
{
colour1 = 15;
}
drawQuad( renderer, x - leftMarginSize, y, colour1, leftMarginSize, p, greyScale );
}
if( rightMarginSize > 0.0 )
{
int colour2 = "0123456789abcdef".indexOf( backgroundColour.charAt( backgroundColour.length() - 1 ) );
if( colour2 < 0 || (greyScale && !isGreyScale( colour2 )) )
{
colour2 = 15;
}
drawQuad( renderer, x + backgroundColour.length() * FONT_WIDTH, y, colour2, rightMarginSize, p, greyScale );
}
for( int i = 0; i < backgroundColour.length(); i++ )
{
int colour = "0123456789abcdef".indexOf( backgroundColour.charAt( i ) );
if( colour < 0 || (greyScale && !isGreyScale( colour )) )
{
colour = 15;
}
drawQuad( renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH, p, greyScale );
}
GlStateManager.disableTexture();
tessellator.draw();
GlStateManager.enableTexture();
}
public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale, Palette p )
{
// Draw the quads
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder renderer = tessellator.getBuffer();
renderer.begin( GL11.GL_TRIANGLES, VertexFormats.POSITION_TEXTURE_COLOR );
for( int i = 0; i < s.length(); i++ )
{
// Switch colour
int colour = "0123456789abcdef".indexOf( textColour.charAt( i ) );
if( colour < 0 || (greyScale && !isGreyScale( colour )) )
{
colour = 0;
}
// Draw char
int index = s.charAt( i );
if( index < 0 || index > 255 )
{
index = '?';
}
drawChar( renderer, x + i * FONT_WIDTH, y, index, colour, p, greyScale );
}
tessellator.draw();
}
public void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )
{
// Draw background
if( backgroundColour != null )
{
// Bind the background texture
m_textureManager.bindTextureInner( BACKGROUND );
// Draw the quads
drawStringBackgroundPart( x, y, backgroundColour, leftMarginSize, rightMarginSize, greyScale, p );
}
// Draw text
if( s != null && textColour != null )
{
// Bind the font texture
bindFont();
// Draw the quads
drawStringTextPart( x, y, s, textColour, greyScale, p );
}
}
public int getStringWidth( String s )
{
if( s == null )
{
return 0;
}
return s.length() * FONT_WIDTH;
}
public void bindFont()
{
m_textureManager.bindTextureInner( FONT );
GlStateManager.texParameter( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
}
}

View File

@@ -0,0 +1,169 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.client.gui.widgets.WidgetWrapper;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Identifier;
import org.lwjgl.glfw.GLFW;
public class GuiComputer<T extends ScreenHandler> extends HandledScreen<T>
{
public static final Identifier BACKGROUND_NORMAL = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_normal.png" );
public static final Identifier BACKGROUND_ADVANCED = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_advanced.png" );
public static final Identifier BACKGROUND_COMMAND = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_command.png" );
public static final Identifier BACKGROUND_COLOUR = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_colour.png" );
private final ComputerFamily m_family;
private final ClientComputer m_computer;
private final int m_termWidth;
private final int m_termHeight;
private WidgetTerminal terminal;
private WidgetWrapper terminalWrapper;
public GuiComputer( T container, PlayerInventory player, ComputerFamily family, ClientComputer computer, int termWidth, int termHeight )
{
super( container, player, new LiteralText( "" ) );
m_family = family;
m_computer = computer;
m_termWidth = termWidth;
m_termHeight = termHeight;
terminal = null;
}
public static GuiComputer<ContainerComputer> create( int id, TileComputer computer, PlayerInventory player )
{
return new GuiComputer<>(
new ContainerComputer( id, computer ), player,
computer.getFamily(),
computer.createClientComputer(),
ComputerCraft.terminalWidth_computer,
ComputerCraft.terminalHeight_computer
);
}
@Override
protected void init()
{
minecraft.keyboard.enableRepeatEvents( true );
int termPxWidth = m_termWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = m_termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
backgroundWidth = termPxWidth + 4 + 24;
backgroundHeight = termPxHeight + 4 + 24;
super.init();
terminal = new WidgetTerminal( minecraft, () -> m_computer, m_termWidth, m_termHeight, 2, 2, 2, 2 );
terminalWrapper = new WidgetWrapper( terminal, 2 + 12 + x, 2 + 12 + y, termPxWidth, termPxHeight );
children.add( terminalWrapper );
setFocused( terminalWrapper );
}
@Override
public void removed()
{
super.removed();
children.remove( terminal );
terminal = null;
minecraft.keyboard.enableRepeatEvents( false );
}
@Override
public void tick()
{
super.tick();
terminal.update();
}
@Override
public void drawBackground( float partialTicks, int mouseX, int mouseY )
{
// Work out where to draw
int startX = terminalWrapper.getX() - 2;
int startY = terminalWrapper.getY() - 2;
int endX = startX + terminalWrapper.getWidth() + 4;
int endY = startY + terminalWrapper.getHeight() + 4;
// Draw terminal
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
// Draw a border around the terminal
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
switch( m_family )
{
case Normal:
default:
minecraft.getTextureManager().bindTextureInner( BACKGROUND_NORMAL );
break;
case Advanced:
minecraft.getTextureManager().bindTextureInner( BACKGROUND_ADVANCED );
break;
case Command:
minecraft.getTextureManager().bindTextureInner( BACKGROUND_COMMAND );
break;
}
blit( startX - 12, startY - 12, 12, 28, 12, 12 );
blit( startX - 12, endY, 12, 40, 12, 12 );
blit( endX, startY - 12, 24, 28, 12, 12 );
blit( endX, endY, 24, 40, 12, 12 );
blit( startX, startY - 12, 0, 0, endX - startX, 12 );
blit( startX, endY, 0, 12, endX - startX, 12 );
blit( startX - 12, startY, 0, 28, 12, endY - startY );
blit( endX, startY, 36, 28, 12, endY - startY );
}
@Override
public void render( int mouseX, int mouseY, float partialTicks )
{
renderBackground( 0 );
super.render( mouseX, mouseY, partialTicks );
drawMouseoverTooltip( mouseX, mouseY );
}
@Override
public boolean keyPressed( int key, int scancode, int modifiers )
{
// When pressing tab, send it to the computer first
return (key == GLFW.GLFW_KEY_TAB && getFocused() == terminalWrapper && terminalWrapper.keyPressed( key, scancode, modifiers ))
|| super.keyPressed( key, scancode, modifiers );
}
@Override
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
{
// Make sure drag events are propagated to children
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|| super.mouseDragged( x, y, button, deltaX, deltaY );
}
@Override
public boolean mouseReleased( double x, double y, int button )
{
// Make sure release events are propagated to children
return (getFocused() != null && getFocused().mouseReleased( x, y, button ))
|| super.mouseReleased( x, y, button );
}
}

View File

@@ -0,0 +1,220 @@
package dan200.computercraft.client.gui;
import dan200.computercraft.core.apis.http.websocket.Websocket;
import dan200.computercraft.shared.util.Config;
import me.shedaniel.clothconfig2.api.ConfigBuilder;
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
import net.minecraft.client.gui.screen.Screen;
import java.util.Arrays;
public final class GuiConfig
{
private GuiConfig() {}
public static Screen getScreen( Screen parentScreen )
{
Config config = Config.get();
ConfigBuilder builder = ConfigBuilder.create().setParentScreen( parentScreen ).setTitle( "gui.computercraft.config.title" ).setSavingRunnable( () -> {
Config.save();
Config.sync();
} );
ConfigEntryBuilder entryBuilder = ConfigEntryBuilder.create();
builder.getOrCreateCategory( key( "general" ) )
.addEntry( entryBuilder.startIntField( key( "computer_space_limit" ), config.general.computer_space_limit )
.setSaveConsumer( v -> config.general.computer_space_limit = v )
.setDefaultValue( Config.defaultConfig.general.computer_space_limit )
.build() )
.addEntry( entryBuilder.startIntField( key( "floppy_space_limit" ), config.general.floppy_space_limit )
.setSaveConsumer( v -> config.general.floppy_space_limit = v )
.setDefaultValue( Config.defaultConfig.general.floppy_space_limit )
.build() )
.addEntry( entryBuilder.startIntField( key( "maximum_open_files" ), config.general.maximum_open_files )
.setSaveConsumer( v -> config.general.maximum_open_files = v )
.setDefaultValue( Config.defaultConfig.general.maximum_open_files )
.setMin( 0 )
.build() )
.addEntry( entryBuilder.startBooleanToggle( key( "disable_lua51_features" ), config.general.disable_lua51_features )
.setSaveConsumer( v -> config.general.disable_lua51_features = v )
.setDefaultValue( Config.defaultConfig.general.disable_lua51_features )
.build() )
.addEntry( entryBuilder.startStrField( key( "default_computer_settings" ), config.general.default_computer_settings )
.setSaveConsumer( v -> config.general.default_computer_settings = v )
.setDefaultValue( Config.defaultConfig.general.default_computer_settings )
.build() )
.addEntry( entryBuilder.startBooleanToggle( key( "debug_enabled" ), config.general.debug_enabled )
.setSaveConsumer( v -> config.general.debug_enabled = v )
.setDefaultValue( Config.defaultConfig.general.debug_enabled )
.build() )
.addEntry( entryBuilder.startBooleanToggle( key( "log_computer_errors" ), config.general.log_computer_errors )
.setSaveConsumer( v -> config.general.log_computer_errors = v )
.setDefaultValue( Config.defaultConfig.general.log_computer_errors )
.build() );
builder.getOrCreateCategory( key( "execution" ) )
.addEntry( entryBuilder.startIntField( key( "execution.computer_threads" ), config.execution.computer_threads )
.setSaveConsumer( v -> config.execution.computer_threads = v )
.setDefaultValue( Config.defaultConfig.execution.computer_threads )
.setMin( 1 )
.requireRestart()
.build() )
.addEntry( entryBuilder.startLongField( key( "execution.max_main_global_time" ), config.execution.max_main_global_time )
.setSaveConsumer( v -> config.execution.max_main_global_time = v )
.setDefaultValue( Config.defaultConfig.execution.max_main_global_time )
.setMin( 1 )
.build() )
.addEntry( entryBuilder.startLongField( key( "execution.max_main_computer_time" ), config.execution.max_main_computer_time )
.setSaveConsumer( v -> config.execution.max_main_computer_time = v )
.setDefaultValue( Config.defaultConfig.execution.max_main_computer_time )
.setMin( 1 )
.build() );
builder.getOrCreateCategory( key( "http" ) )
.addEntry( entryBuilder.startBooleanToggle( key( "http.enabled" ), config.http.enabled )
.setSaveConsumer( v -> config.http.enabled = v )
.setDefaultValue( Config.defaultConfig.http.enabled )
.build() )
.addEntry( entryBuilder.startBooleanToggle( key( "http.websocket_enabled" ), config.http.websocket_enabled )
.setSaveConsumer( v -> config.http.websocket_enabled = v )
.setDefaultValue( Config.defaultConfig.http.websocket_enabled )
.build() )
.addEntry( entryBuilder.startStrList( key( "http.whitelist" ), Arrays.asList( config.http.whitelist ) )
.setSaveConsumer( v -> config.http.whitelist = v.toArray( new String[0] ) )
.setDefaultValue( Arrays.asList( Config.defaultConfig.http.whitelist ) )
.build() )
.addEntry( entryBuilder.startStrList( key( "http.blacklist" ), Arrays.asList( config.http.blacklist ) )
.setSaveConsumer( v -> config.http.blacklist = v.toArray( new String[0] ) )
.setDefaultValue( Arrays.asList( Config.defaultConfig.http.blacklist ) )
.build() )
.addEntry( entryBuilder.startIntField( key( "http.timeout" ), config.http.timeout )
.setSaveConsumer( v -> config.http.timeout = v )
.setDefaultValue( Config.defaultConfig.http.timeout )
.setMin( 0 )
.build() )
.addEntry( entryBuilder.startIntField( key( "http.max_requests" ), config.http.max_requests )
.setSaveConsumer( v -> config.http.max_requests = v )
.setDefaultValue( Config.defaultConfig.http.max_requests )
.setMin( 0 )
.build() )
.addEntry( entryBuilder.startLongField( key( "http.max_download" ), config.http.max_download )
.setSaveConsumer( v -> config.http.max_download = v )
.setDefaultValue( Config.defaultConfig.http.max_download )
.setMin( 0 )
.build() )
.addEntry( entryBuilder.startLongField( key( "http.max_upload" ), config.http.max_upload )
.setSaveConsumer( v -> config.http.max_upload = v )
.setDefaultValue( Config.defaultConfig.http.max_upload )
.setMin( 0 )
.build() )
.addEntry( entryBuilder.startIntField( key( "http.max_websockets" ), config.http.max_websockets )
.setSaveConsumer( v -> config.http.max_websockets = v )
.setDefaultValue( Config.defaultConfig.http.max_websockets )
.setMin( 1 )
.build() )
.addEntry( entryBuilder.startIntField( key( "http.max_websocket_message" ), config.http.max_websocket_message )
.setSaveConsumer( v -> config.http.max_websocket_message = v )
.setDefaultValue( Config.defaultConfig.http.max_websocket_message )
.setMin( 0 )
.setMax( Websocket.MAX_MESSAGE_SIZE )
.build() );
builder.getOrCreateCategory( key( "peripheral" ) )
.addEntry( entryBuilder.startBooleanToggle( key( "peripheral.command_block_enabled" ), config.peripheral.command_block_enabled )
.setSaveConsumer( v -> config.peripheral.command_block_enabled = v )
.setDefaultValue( Config.defaultConfig.peripheral.command_block_enabled )
.build() )
.addEntry( entryBuilder.startIntField( key( "peripheral.modem_range" ), config.peripheral.modem_range )
.setSaveConsumer( v -> config.peripheral.modem_range = v )
.setDefaultValue( Config.defaultConfig.peripheral.modem_range )
.setMin( 0 )
.setMax( Config.MODEM_MAX_RANGE )
.build() )
.addEntry( entryBuilder.startIntField( key( "peripheral.modem_high_altitude_range" ), config.peripheral.modem_high_altitude_range )
.setSaveConsumer( v -> config.peripheral.modem_high_altitude_range = v )
.setDefaultValue( Config.defaultConfig.peripheral.modem_high_altitude_range )
.setMin( 0 )
.setMax( Config.MODEM_MAX_RANGE )
.build() )
.addEntry( entryBuilder.startIntField( key( "peripheral.modem_range_during_storm" ), config.peripheral.modem_range_during_storm )
.setSaveConsumer( v -> config.peripheral.modem_range_during_storm = v )
.setDefaultValue( Config.defaultConfig.peripheral.modem_range_during_storm )
.setMin( 0 )
.setMax( Config.MODEM_MAX_RANGE )
.build() )
.addEntry( entryBuilder.startIntField( key( "peripheral.modem_high_altitude_range_during_storm" ), config.peripheral.modem_high_altitude_range_during_storm )
.setSaveConsumer( v -> config.peripheral.modem_high_altitude_range_during_storm = v )
.setDefaultValue( Config.defaultConfig.peripheral.modem_high_altitude_range_during_storm )
.setMin( 0 )
.setMax( Config.MODEM_MAX_RANGE )
.build() )
.addEntry( entryBuilder.startIntField( key( "peripheral.max_notes_per_tick" ), config.peripheral.max_notes_per_tick )
.setSaveConsumer( v -> config.peripheral.max_notes_per_tick = v )
.setDefaultValue( Config.defaultConfig.peripheral.max_notes_per_tick )
.setMin( 1 )
.build() );
builder.getOrCreateCategory( key( "turtle" ) )
.addEntry( entryBuilder.startBooleanToggle( key( "turtle.need_fuel" ), config.turtle.need_fuel )
.setSaveConsumer( v -> config.turtle.need_fuel = v )
.setDefaultValue( Config.defaultConfig.turtle.need_fuel )
.build() )
.addEntry( entryBuilder.startIntField( key( "turtle.normal_fuel_limit" ), config.turtle.normal_fuel_limit )
.setSaveConsumer( v -> config.turtle.normal_fuel_limit = v )
.setDefaultValue( Config.defaultConfig.turtle.normal_fuel_limit )
.setMin( 0 )
.build() )
.addEntry( entryBuilder.startIntField( key( "turtle.advanced_fuel_limit" ), config.turtle.advanced_fuel_limit )
.setSaveConsumer( v -> config.turtle.advanced_fuel_limit = v )
.setDefaultValue( Config.defaultConfig.turtle.advanced_fuel_limit )
.setMin( 0 )
.build() )
.addEntry( entryBuilder.startBooleanToggle( key( "turtle.obey_block_protection" ), config.turtle.obey_block_protection )
.setSaveConsumer( v -> config.turtle.obey_block_protection = v )
.setDefaultValue( Config.defaultConfig.turtle.obey_block_protection )
.build() )
.addEntry( entryBuilder.startStrList( key( "turtle.disabled_actions" ), Arrays.asList( config.turtle.disabled_actions ) )
.setSaveConsumer( v -> config.turtle.disabled_actions = v.toArray( new String[0] ) )
.setDefaultValue( Arrays.asList( Config.defaultConfig.turtle.disabled_actions ) )
.build() );
return builder.build();
}
private static String key( String name )
{
return "gui.computercraft.config." + name;
}
}

View File

@@ -0,0 +1,49 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.Identifier;
public class GuiDiskDrive extends HandledScreen<ContainerDiskDrive>
{
private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/disk_drive.png" );
public GuiDiskDrive( ContainerDiskDrive container, PlayerInventory inventory )
{
super( container, inventory, ComputerCraft.Blocks.diskDrive.getName() );
}
@Override
protected void drawForeground( int par1, int par2 )
{
String title = getTitle().asFormattedString();
font.draw( title, (backgroundWidth - font.getWidth( title )) / 2.0f, 6, 0x404040 );
font.draw( I18n.translate( "container.inventory" ), 8, (backgroundHeight - 96) + 2, 0x404040 );
}
@Override
protected void drawBackground( float partialTicks, int mouseX, int mouseY )
{
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTextureInner( BACKGROUND );
blit( x, y, 0, 0, backgroundWidth, backgroundHeight );
}
@Override
public void render( int mouseX, int mouseY, float partialTicks )
{
renderBackground();
super.render( mouseX, mouseY, partialTicks );
drawMouseoverTooltip( mouseX, mouseY );
}
}

View File

@@ -0,0 +1,35 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class GuiPocketComputer extends GuiComputer<ContainerPocketComputer>
{
public GuiPocketComputer( ContainerPocketComputer container, PlayerInventory player )
{
super(
container, player,
getFamily( container.getStack() ),
ItemPocketComputer.createClientComputer( container.getStack() ),
ComputerCraft.terminalWidth_pocketComputer,
ComputerCraft.terminalHeight_pocketComputer
);
}
private static ComputerFamily getFamily( ItemStack stack )
{
Item item = stack.getItem();
return item instanceof ItemPocketComputer ? ((ItemPocketComputer) item).getFamily() : ComputerFamily.Normal;
}
}

View File

@@ -0,0 +1,51 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.Identifier;
public class GuiPrinter extends HandledScreen<ContainerPrinter>
{
private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/printer.png" );
public GuiPrinter( ContainerPrinter container, PlayerInventory player )
{
super( container, player, ComputerCraft.Blocks.printer.getName() );
}
@Override
protected void drawForeground( int mouseX, int mouseY )
{
String title = getTitle().asFormattedString();
font.draw( title, (backgroundWidth - font.getWidth( title )) / 2.0f, 6, 0x404040 );
font.draw( I18n.translate( "container.inventory" ), 8, backgroundHeight - 96 + 2, 0x404040 );
}
@Override
protected void drawBackground( float f, int i, int j )
{
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTextureInner( BACKGROUND );
blit( x, y, 0, 0, backgroundWidth, backgroundHeight );
if( handler.isPrinting() ) blit( x + 34, y + 21, 176, 0, 25, 45 );
}
@Override
public void render( int mouseX, int mouseY, float partialTicks )
{
renderBackground();
super.render( mouseX, mouseY, partialTicks );
drawMouseoverTooltip( mouseX, mouseY );
}
}

View File

@@ -0,0 +1,109 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.common.ContainerHeldItem;
import dan200.computercraft.shared.media.items.ItemPrintout;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.entity.player.PlayerInventory;
import org.lwjgl.glfw.GLFW;
import static dan200.computercraft.client.render.PrintoutRenderer.*;
public class GuiPrintout extends HandledScreen<ContainerHeldItem>
{
private final boolean m_book;
private final int m_pages;
private final TextBuffer[] m_text;
private final TextBuffer[] m_colours;
private int m_page;
public GuiPrintout( ContainerHeldItem container, PlayerInventory player )
{
super( container, player, container.getStack().getName() );
backgroundHeight = Y_SIZE;
String[] text = ItemPrintout.getText( container.getStack() );
m_text = new TextBuffer[text.length];
for( int i = 0; i < m_text.length; i++ ) m_text[i] = new TextBuffer( text[i] );
String[] colours = ItemPrintout.getColours( container.getStack() );
m_colours = new TextBuffer[colours.length];
for( int i = 0; i < m_colours.length; i++ ) m_colours[i] = new TextBuffer( colours[i] );
m_page = 0;
m_pages = Math.max( m_text.length / ItemPrintout.LINES_PER_PAGE, 1 );
m_book = ((ItemPrintout) container.getStack().getItem()).getType() == ItemPrintout.Type.BOOK;
}
@Override
public boolean keyPressed( int key, int scancode, int modifiers )
{
if( super.keyPressed( key, scancode, modifiers ) ) return true;
if( key == GLFW.GLFW_KEY_RIGHT )
{
if( m_page < m_pages - 1 ) m_page++;
return true;
}
if( key == GLFW.GLFW_KEY_LEFT )
{
if( m_page > 0 ) m_page--;
return true;
}
return false;
}
@Override
public boolean mouseScrolled( double x, double y, double delta )
{
if( super.mouseScrolled( x, y, delta ) ) return true;
if( delta < 0 )
{
// Scroll up goes to the next page
if( m_page < m_pages - 1 ) m_page++;
return true;
}
if( delta > 0 )
{
// Scroll down goes to the previous page
if( m_page > 0 ) m_page--;
return true;
}
return false;
}
@Override
public void drawBackground( float partialTicks, int mouseX, int mouseY )
{
// Draw the printout
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
GlStateManager.enableDepthTest();
drawBorder( x, y, blitOffset, m_page, m_pages, m_book );
drawText( x + X_TEXT_MARGIN, y + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
}
@Override
public void render( int mouseX, int mouseY, float partialTicks )
{
// We must take the background further back in order to not overlap with our printed pages.
blitOffset--;
renderBackground();
blitOffset++;
super.render( mouseX, mouseY, partialTicks );
drawMouseoverTooltip( mouseX, mouseY );
}
}

View File

@@ -0,0 +1,141 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.client.gui.widgets.WidgetWrapper;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.Identifier;
import org.lwjgl.glfw.GLFW;
public class GuiTurtle extends HandledScreen<ContainerTurtle>
{
private static final Identifier BACKGROUND_NORMAL = new Identifier( "computercraft", "textures/gui/turtle_normal.png" );
private static final Identifier BACKGROUND_ADVANCED = new Identifier( "computercraft", "textures/gui/turtle_advanced.png" );
private ContainerTurtle m_container;
private final ComputerFamily m_family;
private final ClientComputer m_computer;
private WidgetTerminal terminal;
private WidgetWrapper terminalWrapper;
public GuiTurtle( TileTurtle turtle, ContainerTurtle container, PlayerInventory player )
{
super( container, player, turtle.getDisplayName() );
m_container = container;
m_family = turtle.getFamily();
m_computer = turtle.getClientComputer();
backgroundWidth = 254;
backgroundHeight = 217;
}
@Override
protected void init()
{
super.init();
minecraft.keyboard.enableRepeatEvents( true );
int termPxWidth = ComputerCraft.terminalWidth_turtle * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = ComputerCraft.terminalHeight_turtle * FixedWidthFontRenderer.FONT_HEIGHT;
terminal = new WidgetTerminal(
minecraft, () -> m_computer,
ComputerCraft.terminalWidth_turtle,
ComputerCraft.terminalHeight_turtle,
2, 2, 2, 2
);
terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + x, 2 + 8 + y, termPxWidth, termPxHeight );
children.add( terminalWrapper );
setFocused( terminalWrapper );
}
@Override
public void removed()
{
super.removed();
children.remove( terminal );
terminal = null;
minecraft.keyboard.enableRepeatEvents( false );
}
@Override
public void tick()
{
super.tick();
terminal.update();
}
private void drawSelectionSlot( boolean advanced )
{
// Draw selection slot
int slot = m_container.getSelectedSlot();
if( slot >= 0 )
{
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
int slotX = slot % 4;
int slotY = slot / 4;
minecraft.getTextureManager().bindTextureInner( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
blit( x + m_container.m_turtleInvStartX - 2 + slotX * 18, y + m_container.m_playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24 );
}
}
@Override
protected void drawBackground( float partialTicks, int mouseX, int mouseY )
{
// Draw term
boolean advanced = m_family == ComputerFamily.Advanced;
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
// Draw border/inventory
GlStateManager.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTextureInner( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
blit( x, y, 0, 0, backgroundWidth, backgroundHeight );
drawSelectionSlot( advanced );
}
@Override
public void render( int mouseX, int mouseY, float partialTicks )
{
renderBackground();
super.render( mouseX, mouseY, partialTicks );
drawMouseoverTooltip( mouseX, mouseY );
}
@Override
public boolean keyPressed( int key, int scancode, int modifiers )
{
return (key == GLFW.GLFW_KEY_TAB && getFocused() == terminalWrapper && terminalWrapper.keyPressed( key, scancode, modifiers ))
|| super.keyPressed( key, scancode, modifiers );
}
@Override
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
{
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|| super.mouseDragged( x, y, button, deltaX, deltaY );
}
@Override
public boolean mouseReleased( double x, double y, int button )
{
return (getFocused() != null && getFocused().mouseReleased( x, y, button ))
|| super.mouseReleased( x, y, button );
}
}

View File

@@ -0,0 +1,431 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui.widgets;
import com.mojang.blaze3d.platform.GlStateManager;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.IComputer;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.SharedConstants;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Element;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormats;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL11;
import java.util.BitSet;
import java.util.function.Supplier;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.BACKGROUND;
public class WidgetTerminal implements Element
{
private static final float TERMINATE_TIME = 0.5f;
private final MinecraftClient minecraft;
private final Supplier<ClientComputer> computer;
private final int termWidth;
private final int termHeight;
private boolean focused;
private float terminateTimer = -1;
private float rebootTimer = -1;
private float shutdownTimer = -1;
private int lastMouseButton = -1;
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( MinecraftClient minecraft, Supplier<ClientComputer> computer, int termWidth, int termHeight, int leftMargin, int rightMargin, int topMargin, int bottomMargin )
{
this.minecraft = minecraft;
this.computer = computer;
this.termWidth = termWidth;
this.termHeight = termHeight;
this.leftMargin = leftMargin;
this.rightMargin = rightMargin;
this.topMargin = topMargin;
this.bottomMargin = bottomMargin;
}
@Override
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 ) );
}
return true;
}
@Override
public boolean keyPressed( int key, int scancode, int modifiers )
{
if( key == GLFW.GLFW_KEY_ESCAPE ) return false;
if( (modifiers & GLFW.GLFW_MOD_CONTROL) != 0 )
{
switch( key )
{
case GLFW.GLFW_KEY_T:
if( terminateTimer < 0 ) terminateTimer = 0;
return true;
case GLFW.GLFW_KEY_S:
if( shutdownTimer < 0 ) shutdownTimer = 0;
return true;
case GLFW.GLFW_KEY_R:
if( rebootTimer < 0 ) rebootTimer = 0;
return true;
case GLFW.GLFW_KEY_V:
// Ctrl+V for paste
String clipboard = minecraft.keyboard.getClipboard();
if( clipboard != null )
{
// Clip to the first occurrence of \r or \n
int newLineIndex1 = clipboard.indexOf( "\r" );
int newLineIndex2 = clipboard.indexOf( "\n" );
if( newLineIndex1 >= 0 && newLineIndex2 >= 0 )
{
clipboard = clipboard.substring( 0, Math.min( newLineIndex1, newLineIndex2 ) );
}
else if( newLineIndex1 >= 0 )
{
clipboard = clipboard.substring( 0, newLineIndex1 );
}
else if( newLineIndex2 >= 0 )
{
clipboard = clipboard.substring( 0, newLineIndex2 );
}
// Filter the string
clipboard = SharedConstants.stripInvalidChars( clipboard );
if( !clipboard.isEmpty() )
{
// Clip to 512 characters and queue the event
if( clipboard.length() > 512 ) clipboard = clipboard.substring( 0, 512 );
queueEvent( "paste", clipboard );
}
return true;
}
}
}
if( key >= 0 && terminateTimer < 0 && rebootTimer < 0 && shutdownTimer < 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 );
}
return true;
}
@Override
public boolean keyReleased( int key, int scancode, int modifiers )
{
// Queue the "key_up" event and remove from the down set
if( key >= 0 && keysDown.get( key ) )
{
keysDown.set( key, false );
IComputer computer = this.computer.get();
if( computer != null ) computer.keyUp( key );
}
switch( key )
{
case GLFW.GLFW_KEY_T:
terminateTimer = -1;
break;
case GLFW.GLFW_KEY_R:
rebootTimer = -1;
break;
case GLFW.GLFW_KEY_S:
shutdownTimer = -1;
break;
case GLFW.GLFW_KEY_LEFT_CONTROL:
case GLFW.GLFW_KEY_RIGHT_CONTROL:
terminateTimer = rebootTimer = shutdownTimer = -1;
break;
}
return true;
}
@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;
Terminal term = computer.getTerminal();
if( term != null )
{
int charX = (int) (mouseX / FixedWidthFontRenderer.FONT_WIDTH);
int charY = (int) (mouseY / FixedWidthFontRenderer.FONT_HEIGHT);
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
computer.mouseClick( button + 1, charX + 1, charY + 1 );
lastMouseButton = button;
lastMouseX = charX;
lastMouseY = charY;
}
return true;
}
@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;
Terminal term = computer.getTerminal();
if( term != null )
{
int charX = (int) (mouseX / FixedWidthFontRenderer.FONT_WIDTH);
int charY = (int) (mouseY / FixedWidthFontRenderer.FONT_HEIGHT);
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
if( lastMouseButton == button )
{
computer.mouseUp( lastMouseButton + 1, charX + 1, charY + 1 );
lastMouseButton = -1;
}
lastMouseX = charX;
lastMouseY = charY;
}
return false;
}
@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;
Terminal term = computer.getTerminal();
if( term != null )
{
int charX = (int) (mouseX / FixedWidthFontRenderer.FONT_WIDTH);
int charY = (int) (mouseY / FixedWidthFontRenderer.FONT_HEIGHT);
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
computer.mouseDrag( button + 1, charX + 1, charY + 1 );
lastMouseX = charX;
lastMouseY = charY;
lastMouseButton = button;
}
return false;
}
@Override
public boolean mouseScrolled( double mouseX, double mouseY, double delta )
{
ClientComputer computer = this.computer.get();
if( computer == null || !computer.isColour() || delta == 0 ) return false;
Terminal term = computer.getTerminal();
if( term != null )
{
int charX = (int) (mouseX / FixedWidthFontRenderer.FONT_WIDTH);
int charY = (int) (mouseY / FixedWidthFontRenderer.FONT_HEIGHT);
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
computer.mouseScroll( delta < 0 ? 1 : -1, charX + 1, charY + 1 );
lastMouseX = charX;
lastMouseY = charY;
}
return true;
}
public void update()
{
if( terminateTimer >= 0 && terminateTimer < TERMINATE_TIME && (terminateTimer += 0.05f) > TERMINATE_TIME )
{
queueEvent( "terminate" );
}
if( shutdownTimer >= 0 && shutdownTimer < TERMINATE_TIME && (shutdownTimer += 0.05f) > TERMINATE_TIME )
{
ClientComputer computer = this.computer.get();
if( computer != null ) computer.shutdown();
}
if( rebootTimer >= 0 && rebootTimer < TERMINATE_TIME && (rebootTimer += 0.05f) > TERMINATE_TIME )
{
ClientComputer computer = this.computer.get();
if( computer != null ) computer.reboot();
}
}
@Override
public boolean changeFocus( boolean reverse )
{
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 );
}
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 );
lastMouseButton = -1;
}
shutdownTimer = terminateTimer = rebootTimer = -1;
}
focused = !focused;
return true;
}
public void draw( int originX, int originY )
{
synchronized( computer )
{
// Draw the screen contents
ClientComputer computer = this.computer.get();
Terminal terminal = computer != null ? computer.getTerminal() : null;
if( terminal != null )
{
// Draw the terminal
boolean greyscale = !computer.isColour();
Palette palette = terminal.getPalette();
// Get the data from the terminal first
// Unfortunately we have to keep the lock for the whole of drawing, so the text doesn't change under us.
FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance();
boolean tblink = terminal.getCursorBlink() && FrameInfo.getGlobalCursorBlink();
int tw = terminal.getWidth();
int th = terminal.getHeight();
int tx = terminal.getCursorX();
int ty = terminal.getCursorY();
// Draw margins
TextBuffer emptyLine = new TextBuffer( ' ', tw );
if( topMargin > 0 )
{
fontRenderer.drawString( emptyLine, originX, originY - topMargin,
terminal.getTextColourLine( 0 ), terminal.getBackgroundColourLine( 0 ),
leftMargin, rightMargin, greyscale, palette );
}
if( bottomMargin > 0 )
{
fontRenderer.drawString( emptyLine, originX, originY + bottomMargin + (th - 1) * FixedWidthFontRenderer.FONT_HEIGHT,
terminal.getTextColourLine( th - 1 ), terminal.getBackgroundColourLine( th - 1 ),
leftMargin, rightMargin, greyscale, palette );
}
// Draw lines
int y = originY;
for( int line = 0; line < th; line++ )
{
TextBuffer text = terminal.getLine( line );
TextBuffer colour = terminal.getTextColourLine( line );
TextBuffer backgroundColour = terminal.getBackgroundColourLine( line );
fontRenderer.drawString( text, originX, y, colour, backgroundColour, leftMargin, rightMargin, greyscale, palette );
y += FixedWidthFontRenderer.FONT_HEIGHT;
}
if( tblink && tx >= 0 && ty >= 0 && tx < tw && ty < th )
{
TextBuffer cursor = new TextBuffer( '_', 1 );
TextBuffer cursorColour = new TextBuffer( "0123456789abcdef".charAt( terminal.getTextColour() ), 1 );
fontRenderer.drawString(
cursor,
originX + FixedWidthFontRenderer.FONT_WIDTH * tx,
originY + FixedWidthFontRenderer.FONT_HEIGHT * ty,
cursorColour, null,
0, 0,
greyscale,
palette
);
}
}
else
{
// Draw a black background
Colour black = Colour.Black;
GlStateManager.color4f( black.getR(), black.getG(), black.getB(), 1.0f );
try
{
int x = originX - leftMargin;
int y = originY - rightMargin;
int width = termWidth * FixedWidthFontRenderer.FONT_WIDTH + leftMargin + rightMargin;
int height = termHeight * FixedWidthFontRenderer.FONT_HEIGHT + topMargin + bottomMargin;
minecraft.getTextureManager().bindTextureInner( BACKGROUND );
Tessellator tesslector = Tessellator.getInstance();
BufferBuilder buffer = tesslector.getBuffer();
buffer.begin( GL11.GL_QUADS, VertexFormats.POSITION_TEXTURE );
buffer.vertex( x, y + height, 0 ).texture( 0 / 256.0, height / 256.0 ).next();
buffer.vertex( x + width, y + height, 0 ).texture( width / 256.0, height / 256.0 ).next();
buffer.vertex( x + width, y, 0 ).texture( width / 256.0, 0 / 256.0 ).next();
buffer.vertex( x, y, 0 ).texture( 0 / 256.0, 0 / 256.0 ).next();
tesslector.draw();
}
finally
{
GlStateManager.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
}
}
}
}
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 );
}
}

View File

@@ -0,0 +1,113 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui.widgets;
import net.minecraft.client.gui.Element;
public class WidgetWrapper implements Element
{
private final Element listener;
private final int x;
private final int y;
private final int width;
private final int height;
public WidgetWrapper( Element 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 void mouseMoved( double x, double y )
{
double dx = x - this.x, dy = y - this.y;
if( dx >= 0 && dx < width && dy >= 0 && dy < height ) listener.mouseMoved( dx, dy );
}
@Override
public boolean changeFocus( boolean reverse )
{
return listener.changeFocus( reverse );
}
@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;
}
}