From cb9a10cdcf7b415f32badd8cb6e2fc817851498e Mon Sep 17 00:00:00 2001 From: TehStoneMan Date: Sat, 4 Apr 2015 23:34:27 +1100 Subject: [PATCH 1/3] Updates to Logistical Sorter GUI Add scroll wheel control to scrollbar. Dim scrollbar when nothing to scroll. Remove blank space when scrolled to end of list. Add move filter up/down buttons to GUI (Not yet functional) --- .../client/gui/GuiLogisticalSorter.java | 759 ++++++++++-------- .../mekanism/gui/GuiLogisticalSorter.png | Bin 4812 -> 2519 bytes .../mekanism/gui/GuiLogisticalSorter.xcf | Bin 0 -> 105950 bytes .../resources/assets/mekanism/lang/en_US.lang | 2 + 4 files changed, 413 insertions(+), 348 deletions(-) create mode 100644 src/main/resources/assets/mekanism/gui/GuiLogisticalSorter.xcf diff --git a/src/main/java/mekanism/client/gui/GuiLogisticalSorter.java b/src/main/java/mekanism/client/gui/GuiLogisticalSorter.java index 125a20faa..12be32088 100644 --- a/src/main/java/mekanism/client/gui/GuiLogisticalSorter.java +++ b/src/main/java/mekanism/client/gui/GuiLogisticalSorter.java @@ -29,49 +29,81 @@ import mekanism.common.util.MekanismUtils.ResourceType; import net.minecraft.client.gui.GuiButton; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; -@SideOnly(Side.CLIENT) +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly( Side.CLIENT ) public class GuiLogisticalSorter extends GuiMekanism { - public TileEntityLogisticalSorter tileEntity; + public TileEntityLogisticalSorter tileEntity; - public boolean isDragging = false; + /** + * True if the left mouse button was held down last time drawScreen was + * called. + */ + private boolean wasClicking; - public int dragOffset = 0; + // Buttons + int BUTTON_NEW = 0; - public int stackSwitch = 0; + /** Amount scrolled in filter list (0 = top, 1 = bottom) */ + public float scroll; + /** True if the scrollbar is being dragged */ + public boolean isDragging = false; - public Map oreDictStacks = new HashMap(); - public Map modIDStacks = new HashMap(); + // Scrollbar dimensions + private final int scrollX = 154; + private final int scrollY = 18; + private final int scrollW = 12; + private final int scrollH = 138; - public float scroll; + // Filter dimensions + private final int filterX = 56; + private final int filterY = 18; + private final int filterW = 96; + private final int filterH = 29; - public GuiLogisticalSorter(EntityPlayer player, TileEntityLogisticalSorter tentity) + public int dragOffset = 0; + + public int stackSwitch = 0; + + public Map< TOreDictFilter, StackData > oreDictStacks = new HashMap< TOreDictFilter, StackData >(); + public Map< TModIDFilter, StackData > modIDStacks = new HashMap< TModIDFilter, StackData >(); + + public GuiLogisticalSorter( EntityPlayer player, TileEntityLogisticalSorter entity ) { - super(tentity, new ContainerNull(player, tentity)); - tileEntity = tentity; - guiElements.add(new GuiRedstoneControl(this, tileEntity, MekanismUtils.getResource(ResourceType.GUI, "GuiLogisticalSorter.png"))); + super( entity, new ContainerNull( player, entity ) ); + tileEntity = entity; + + // Set size of gui + // xSize = 189; + // ySize = 166; + + // Add common Mekanism gui elements + guiElements.add( new GuiRedstoneControl( this, tileEntity, MekanismUtils.getResource( ResourceType.GUI, "GuiLogisticalSorter.png" ) ) ); } public int getScroll() { - return Math.max(Math.min((int)(scroll*123), 123), 0); + // Calculate thumb position along scrollbar + return Math.max( Math.min( (int)( scroll * 123 ), 123 ), 0 ); } + // Get index to displayed filters public int getFilterIndex() { - if(tileEntity.filters.size() <= 4) + if( needsScrollBars() ) { - return 0; + final int scrollSize = tileEntity.filters.size() - 4; + return (int)( ( scrollSize + 0.5 ) * scroll ); } - - return (int)((tileEntity.filters.size()*scroll) - ((4F/(float)tileEntity.filters.size()))*scroll); + return 0; } @Override @@ -79,482 +111,513 @@ public class GuiLogisticalSorter extends GuiMekanism { super.updateScreen(); - if(stackSwitch > 0) - { + // Decrease timer for stack display rotation + if( stackSwitch > 0 ) stackSwitch--; - } - if(stackSwitch == 0) + // Update displayed stacks + if( stackSwitch == 0 ) { - for(Map.Entry entry : oreDictStacks.entrySet()) - { - if(entry.getValue().iterStacks != null && entry.getValue().iterStacks.size() > 0) + for( final Map.Entry< TOreDictFilter, StackData > entry : oreDictStacks.entrySet() ) + if( entry.getValue().iterStacks != null && entry.getValue().iterStacks.size() > 0 ) { - if(entry.getValue().stackIndex == -1 || entry.getValue().stackIndex == entry.getValue().iterStacks.size()-1) - { + if( entry.getValue().stackIndex == -1 || entry.getValue().stackIndex == entry.getValue().iterStacks.size() - 1 ) entry.getValue().stackIndex = 0; - } - else if(entry.getValue().stackIndex < entry.getValue().iterStacks.size()-1) - { - entry.getValue().stackIndex++; - } + else + if( entry.getValue().stackIndex < entry.getValue().iterStacks.size() - 1 ) + entry.getValue().stackIndex++; - entry.getValue().renderStack = entry.getValue().iterStacks.get(entry.getValue().stackIndex); + entry.getValue().renderStack = entry.getValue().iterStacks.get( entry.getValue().stackIndex ); } - } - - for(Map.Entry entry : modIDStacks.entrySet()) - { - if(entry.getValue().iterStacks != null && entry.getValue().iterStacks.size() > 0) + + for( final Map.Entry< TModIDFilter, StackData > entry : modIDStacks.entrySet() ) + if( entry.getValue().iterStacks != null && entry.getValue().iterStacks.size() > 0 ) { - if(entry.getValue().stackIndex == -1 || entry.getValue().stackIndex == entry.getValue().iterStacks.size()-1) - { + if( entry.getValue().stackIndex == -1 || entry.getValue().stackIndex == entry.getValue().iterStacks.size() - 1 ) entry.getValue().stackIndex = 0; - } - else if(entry.getValue().stackIndex < entry.getValue().iterStacks.size()-1) - { - entry.getValue().stackIndex++; - } + else + if( entry.getValue().stackIndex < entry.getValue().iterStacks.size() - 1 ) + entry.getValue().stackIndex++; - entry.getValue().renderStack = entry.getValue().iterStacks.get(entry.getValue().stackIndex); + entry.getValue().renderStack = entry.getValue().iterStacks.get( entry.getValue().stackIndex ); } - } stackSwitch = 20; } - else { - for(Map.Entry entry : oreDictStacks.entrySet()) - { - if(entry.getValue().iterStacks != null && entry.getValue().iterStacks.size() == 0) - { - entry.getValue().renderStack = null; - } - } - - for(Map.Entry entry : modIDStacks.entrySet()) - { - if(entry.getValue().iterStacks != null && entry.getValue().iterStacks.size() == 0) - { - entry.getValue().renderStack = null; - } - } - } - - Set oreDictFilters = new HashSet(); - Set modIDFilters = new HashSet(); - - for(int i = 0; i < 4; i++) + else { - if(tileEntity.filters.get(getFilterIndex()+i) instanceof TOreDictFilter) - { - oreDictFilters.add((TOreDictFilter)tileEntity.filters.get(getFilterIndex()+i)); - } - else if(tileEntity.filters.get(getFilterIndex()+i) instanceof TModIDFilter) - { - modIDFilters.add((TModIDFilter)tileEntity.filters.get(getFilterIndex()+i)); - } + for( final Map.Entry< TOreDictFilter, StackData > entry : oreDictStacks.entrySet() ) + if( entry.getValue().iterStacks != null && entry.getValue().iterStacks.size() == 0 ) + entry.getValue().renderStack = null; + + for( final Map.Entry< TModIDFilter, StackData > entry : modIDStacks.entrySet() ) + if( entry.getValue().iterStacks != null && entry.getValue().iterStacks.size() == 0 ) + entry.getValue().renderStack = null; } - for(TransporterFilter filter : tileEntity.filters) - { - if(filter instanceof TOreDictFilter && !oreDictFilters.contains(filter)) + final Set< TOreDictFilter > oreDictFilters = new HashSet< TOreDictFilter >(); + final Set< TModIDFilter > modIDFilters = new HashSet< TModIDFilter >(); + + for( int i = 0; i < 4; i++ ) + if( tileEntity.filters.get( getFilterIndex() + i ) instanceof TOreDictFilter ) + oreDictFilters.add( (TOreDictFilter)tileEntity.filters.get( getFilterIndex() + i ) ); + else + if( tileEntity.filters.get( getFilterIndex() + i ) instanceof TModIDFilter ) + modIDFilters.add( (TModIDFilter)tileEntity.filters.get( getFilterIndex() + i ) ); + + for( final TransporterFilter filter : tileEntity.filters ) + if( filter instanceof TOreDictFilter && !oreDictFilters.contains( filter ) ) { - if(oreDictStacks.containsKey(filter)) - { - oreDictStacks.remove(filter); - } + if( oreDictStacks.containsKey( filter ) ) + oreDictStacks.remove( filter ); } - else if(filter instanceof TModIDFilter && !modIDFilters.contains(filter)) - { - if(modIDStacks.containsKey(filter)) - { - modIDStacks.remove(filter); - } - } - } + else + if( filter instanceof TModIDFilter && !modIDFilters.contains( filter ) ) + if( modIDStacks.containsKey( filter ) ) + modIDStacks.remove( filter ); } @Override - public void mouseClicked(int mouseX, int mouseY, int button) + public void mouseClicked( int mouseX, int mouseY, int mouseBtn ) { - super.mouseClicked(mouseX, mouseY, button); + super.mouseClicked( mouseX, mouseY, mouseBtn ); - int xAxis = (mouseX - (width - xSize) / 2); - int yAxis = (mouseY - (height - ySize) / 2); + // Get mouse position relative to gui + final int xAxis = mouseX - guiLeft; + final int yAxis = mouseY - guiTop; - if(button == 0) + if( mouseBtn == 0 ) { - if(xAxis >= 154 && xAxis <= 166 && yAxis >= getScroll()+18 && yAxis <= getScroll()+18+15) - { - if(tileEntity.filters.size()>4) + // Check for scrollbar interaction + if( xAxis >= 154 && xAxis <= 166 && yAxis >= getScroll() + 18 && yAxis <= getScroll() + 18 + 15 ) + if( needsScrollBars() ) { - dragOffset = yAxis - (getScroll()+18); + dragOffset = yAxis - ( getScroll() + 18 ); isDragging = true; } - else { + else scroll = 0; - } - } - for(int i = 0; i < 4; i++) - { - if(tileEntity.filters.get(getFilterIndex()+i) != null) + // Check for filter interaction + for( int i = 0; i < 4; i++ ) + if( tileEntity.filters.get( getFilterIndex() + i ) != null ) { - int yStart = i*29 + 18; + final int yStart = i * 29 + 18; - if(xAxis >= 56 && xAxis <= 152 && yAxis >= yStart && yAxis <= yStart+29) + if( xAxis >= 56 && xAxis <= 152 && yAxis >= yStart && yAxis <= yStart + 29 ) { - TransporterFilter filter = tileEntity.filters.get(getFilterIndex()+i); + // Check for sorting button + final int arrowX = filterX + filterW - 12; + if( getFilterIndex() + i > 0 ) + if( xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 14 && yAxis <= yStart + 20 ) + // Process up button click + return; + if( getFilterIndex() + i < tileEntity.filters.size() - 1 ) + if( xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 21 && yAxis <= yStart + 27 ) + // Process down button click + return; - if(filter instanceof TItemStackFilter) + final TransporterFilter filter = tileEntity.filters.get( getFilterIndex() + i ); + + if( filter instanceof TItemStackFilter ) { - SoundHandler.playSound("gui.button.press"); - Mekanism.packetHandler.sendToServer(new LogisticalSorterGuiMessage(SorterGuiPacket.SERVER_INDEX, Coord4D.get(tileEntity), 1, getFilterIndex()+i, 0)); - } - else if(filter instanceof TOreDictFilter) - { - SoundHandler.playSound("gui.button.press"); - Mekanism.packetHandler.sendToServer(new LogisticalSorterGuiMessage(SorterGuiPacket.SERVER_INDEX, Coord4D.get(tileEntity), 2, getFilterIndex()+i, 0)); - } - else if(filter instanceof TMaterialFilter) - { - SoundHandler.playSound("gui.button.press"); - Mekanism.packetHandler.sendToServer(new LogisticalSorterGuiMessage(SorterGuiPacket.SERVER_INDEX, Coord4D.get(tileEntity), 3, getFilterIndex()+i, 0)); - } - else if(filter instanceof TModIDFilter) - { - SoundHandler.playSound("gui.button.press"); - Mekanism.packetHandler.sendToServer(new LogisticalSorterGuiMessage(SorterGuiPacket.SERVER_INDEX, Coord4D.get(tileEntity), 5, getFilterIndex()+i, 0)); + SoundHandler.playSound( "gui.button.press" ); + Mekanism.packetHandler.sendToServer( new LogisticalSorterGuiMessage( SorterGuiPacket.SERVER_INDEX, Coord4D + .get( tileEntity ), 1, getFilterIndex() + i, 0 ) ); } + else + if( filter instanceof TOreDictFilter ) + { + SoundHandler.playSound( "gui.button.press" ); + Mekanism.packetHandler.sendToServer( new LogisticalSorterGuiMessage( SorterGuiPacket.SERVER_INDEX, Coord4D + .get( tileEntity ), 2, getFilterIndex() + i, 0 ) ); + } + else + if( filter instanceof TMaterialFilter ) + { + SoundHandler.playSound( "gui.button.press" ); + Mekanism.packetHandler.sendToServer( new LogisticalSorterGuiMessage( SorterGuiPacket.SERVER_INDEX, Coord4D + .get( tileEntity ), 3, getFilterIndex() + i, 0 ) ); + } + else + if( filter instanceof TModIDFilter ) + { + SoundHandler.playSound( "gui.button.press" ); + Mekanism.packetHandler.sendToServer( new LogisticalSorterGuiMessage( SorterGuiPacket.SERVER_INDEX, Coord4D + .get( tileEntity ), 5, getFilterIndex() + i, 0 ) ); + } } } + + // Check for auto eject button + if( xAxis >= 12 && xAxis <= 26 && yAxis >= 110 && yAxis <= 124 ) + { + final ArrayList data = new ArrayList(); + data.add( 1 ); + + Mekanism.packetHandler.sendToServer( new TileEntityMessage( Coord4D.get( tileEntity ), data ) ); + SoundHandler.playSound( "gui.button.press" ); } - if(xAxis >= 12 && xAxis <= 26 && yAxis >= 110 && yAxis <= 124) + // Check for round robin button + if( xAxis >= 12 && xAxis <= 26 && yAxis >= 84 && yAxis <= 98 ) { - ArrayList data = new ArrayList(); - data.add(1); + final ArrayList data = new ArrayList(); + data.add( 2 ); - Mekanism.packetHandler.sendToServer(new TileEntityMessage(Coord4D.get(tileEntity), data)); - SoundHandler.playSound("gui.button.press"); - } - - if(xAxis >= 12 && xAxis <= 26 && yAxis >= 84 && yAxis <= 98) - { - ArrayList data = new ArrayList(); - data.add(2); - - Mekanism.packetHandler.sendToServer(new TileEntityMessage(Coord4D.get(tileEntity), data)); - SoundHandler.playSound("gui.button.press"); + Mekanism.packetHandler.sendToServer( new TileEntityMessage( Coord4D.get( tileEntity ), data ) ); + SoundHandler.playSound( "gui.button.press" ); } } - if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && button == 0) - { - button = 2; - } + if( Keyboard.isKeyDown( Keyboard.KEY_LSHIFT ) && mouseBtn == 0 ) + mouseBtn = 2; - if(xAxis >= 13 && xAxis <= 29 && yAxis >= 137 && yAxis <= 153) + // Check for default colour button + if( xAxis >= 13 && xAxis <= 29 && yAxis >= 137 && yAxis <= 153 ) { - ArrayList data = new ArrayList(); - data.add(0); - data.add(button); + final ArrayList data = new ArrayList(); + data.add( 0 ); + data.add( mouseBtn ); - Mekanism.packetHandler.sendToServer(new TileEntityMessage(Coord4D.get(tileEntity), data)); - SoundHandler.playSound("mekanism:etc.Ding"); + Mekanism.packetHandler.sendToServer( new TileEntityMessage( Coord4D.get( tileEntity ), data ) ); + SoundHandler.playSound( "mekanism:etc.Ding" ); } } @Override - protected void mouseClickMove(int mouseX, int mouseY, int button, long ticks) + protected void mouseClickMove( int mouseX, int mouseY, int button, long ticks ) { - super.mouseClickMove(mouseX, mouseY, button, ticks); + super.mouseClickMove( mouseX, mouseY, button, ticks ); - int xAxis = (mouseX - (width - xSize) / 2); - int yAxis = (mouseY - (height - ySize) / 2); + // Get mouse position relative to gui + final int xAxis = mouseX - guiLeft; + final int yAxis = mouseY - guiTop; - if(isDragging) - { - scroll = Math.min(Math.max((float)(yAxis-18-dragOffset)/123F, 0), 1); - } + if( isDragging ) + scroll = Math.min( Math.max( ( yAxis - 18 - dragOffset ) / 123F, 0 ), 1 ); } @Override - protected void mouseMovedOrUp(int mouseX, int mouseY, int type) + protected void mouseMovedOrUp( int mouseX, int mouseY, int type ) { - super.mouseMovedOrUp(mouseX, mouseY, type); + super.mouseMovedOrUp( mouseX, mouseY, type ); - if(type == 0 && isDragging) + if( type == 0 && isDragging ) { dragOffset = 0; isDragging = false; } } + /** + * Handles mouse input. + */ + @Override + public void handleMouseInput() + { + super.handleMouseInput(); + int i = Mouse.getEventDWheel(); + + if( i != 0 && needsScrollBars() ) + { + final int j = tileEntity.filters.size() - 4; + + if( i > 0 ) + i = 1; + + if( i < 0 ) + i = -1; + + scroll = (float)( scroll - (double)i / (double)j ); + + if( scroll < 0.0F ) + scroll = 0.0F; + + if( scroll > 1.0F ) + scroll = 1.0F; + } + } + @Override public void initGui() { super.initGui(); - int guiWidth = (width - xSize) / 2; - int guiHeight = (height - ySize) / 2; - + // Add buttons to gui buttonList.clear(); - buttonList.add(new GuiButton(0, guiWidth + 56, guiHeight + 136, 96, 20, MekanismUtils.localize("gui.newFilter"))); + buttonList.add( new GuiButton( BUTTON_NEW, guiLeft + 56, guiTop + 136, 96, 20, MekanismUtils.localize( "gui.newFilter" ) ) ); } @Override - protected void actionPerformed(GuiButton guibutton) + protected void actionPerformed( GuiButton guibutton ) { - super.actionPerformed(guibutton); + super.actionPerformed( guibutton ); - if(guibutton.id == 0) - { - Mekanism.packetHandler.sendToServer(new LogisticalSorterGuiMessage(SorterGuiPacket.SERVER, Coord4D.get(tileEntity), 4, 0, 0)); - } + if( guibutton.id == BUTTON_NEW ) + Mekanism.packetHandler.sendToServer( new LogisticalSorterGuiMessage( SorterGuiPacket.SERVER, Coord4D.get( tileEntity ), 4, 0, 0 ) ); } @Override - protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) + protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY ) { - int xAxis = (mouseX - (width - xSize) / 2); - int yAxis = (mouseY - (height - ySize) / 2); + // Get mouse position relative to gui + final int xAxis = mouseX - guiLeft; + final int yAxis = mouseY - guiTop; - fontRendererObj.drawString(tileEntity.getInventoryName(), 43, 6, 0x404040); + // Write to info display + fontRendererObj.drawString( tileEntity.getInventoryName(), 43, 6, 0x404040 ); - fontRendererObj.drawString(MekanismUtils.localize("gui.filters") + ":", 11, 19, 0x00CD00); - fontRendererObj.drawString("T: " + tileEntity.filters.size(), 11, 28, 0x00CD00); + fontRendererObj.drawString( MekanismUtils.localize( "gui.filters" ) + ":", 11, 19, 0x00CD00 ); + fontRendererObj.drawString( "T: " + tileEntity.filters.size(), 11, 28, 0x00CD00 ); - fontRendererObj.drawString("RR:", 12, 74, 0x00CD00); - fontRendererObj.drawString(MekanismUtils.localize("gui." + (tileEntity.roundRobin ? "on" : "off")), 27, 86, 0x00CD00); + fontRendererObj.drawString( "RR:", 12, 74, 0x00CD00 ); + fontRendererObj.drawString( MekanismUtils.localize( "gui." + ( tileEntity.roundRobin ? "on" : "off" ) ), 27, 86, 0x00CD00 ); - fontRendererObj.drawString(MekanismUtils.localize("gui.logisticalSorter.auto") + ":", 12, 100, 0x00CD00); - fontRendererObj.drawString(MekanismUtils.localize("gui." + (tileEntity.autoEject ? "on" : "off")), 27, 112, 0x00CD00); + fontRendererObj.drawString( MekanismUtils.localize( "gui.logisticalSorter.auto" ) + ":", 12, 100, 0x00CD00 ); + fontRendererObj.drawString( MekanismUtils.localize( "gui." + ( tileEntity.autoEject ? "on" : "off" ) ), 27, 112, 0x00CD00 ); - fontRendererObj.drawString(MekanismUtils.localize("gui.logisticalSorter.default") + ":", 12, 126, 0x00CD00); + fontRendererObj.drawString( MekanismUtils.localize( "gui.logisticalSorter.default" ) + ":", 12, 126, 0x00CD00 ); - for(int i = 0; i < 4; i++) - { - if(tileEntity.filters.get(getFilterIndex()+i) != null) + // Draw filters + for( int i = 0; i < 4; i++ ) + if( tileEntity.filters.get( getFilterIndex() + i ) != null ) { - TransporterFilter filter = tileEntity.filters.get(getFilterIndex()+i); - int yStart = i*29 + 18; + final TransporterFilter filter = tileEntity.filters.get( getFilterIndex() + i ); + final int yStart = i * filterH + filterY; - if(filter instanceof TItemStackFilter) + if( filter instanceof TItemStackFilter ) { - TItemStackFilter itemFilter = (TItemStackFilter)filter; + final TItemStackFilter itemFilter = (TItemStackFilter)filter; - if(itemFilter.itemType != null) + if( itemFilter.itemType != null ) { GL11.glPushMatrix(); - GL11.glEnable(GL11.GL_LIGHTING); - itemRender.renderItemAndEffectIntoGUI(fontRendererObj, mc.getTextureManager(), itemFilter.itemType, 59, yStart + 3); - GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable( GL11.GL_LIGHTING ); + itemRender.renderItemAndEffectIntoGUI( fontRendererObj, mc.getTextureManager(), itemFilter.itemType, 59, yStart + 3 ); + GL11.glDisable( GL11.GL_LIGHTING ); GL11.glPopMatrix(); } - fontRendererObj.drawString(MekanismUtils.localize("gui.itemFilter"), 78, yStart + 2, 0x404040); - fontRendererObj.drawString(filter.color != null ? filter.color.getName() : MekanismUtils.localize("gui.none"), 78, yStart + 11, 0x404040); + fontRendererObj.drawString( MekanismUtils.localize( "gui.itemFilter" ), 78, yStart + 2, 0x404040 ); + fontRendererObj.drawString( filter.color != null ? filter.color.getName() : MekanismUtils.localize( "gui.none" ), 78, + yStart + 11, 0x404040 ); } - else if(filter instanceof TOreDictFilter) - { - TOreDictFilter oreFilter = (TOreDictFilter)filter; - - if(!oreDictStacks.containsKey(oreFilter)) + else + if( filter instanceof TOreDictFilter ) { - updateStackList(oreFilter); + final TOreDictFilter oreFilter = (TOreDictFilter)filter; + + if( !oreDictStacks.containsKey( oreFilter ) ) + updateStackList( oreFilter ); + + if( oreDictStacks.get( filter ).renderStack != null ) + try + { + GL11.glPushMatrix(); + GL11.glEnable( GL11.GL_LIGHTING ); + itemRender.renderItemAndEffectIntoGUI( fontRendererObj, mc.getTextureManager(), + oreDictStacks.get( filter ).renderStack, 59, yStart + 3 ); + GL11.glDisable( GL11.GL_LIGHTING ); + GL11.glPopMatrix(); + } + catch( final Exception e ) + {} + + fontRendererObj.drawString( MekanismUtils.localize( "gui.oredictFilter" ), 78, yStart + 2, 0x404040 ); + fontRendererObj.drawString( filter.color != null ? filter.color.getName() : MekanismUtils.localize( "gui.none" ), 78, + yStart + 11, 0x404040 ); } + else + if( filter instanceof TMaterialFilter ) + { + final TMaterialFilter itemFilter = (TMaterialFilter)filter; - if(oreDictStacks.get(filter).renderStack != null) - { - try { - GL11.glPushMatrix(); - GL11.glEnable(GL11.GL_LIGHTING); - itemRender.renderItemAndEffectIntoGUI(fontRendererObj, mc.getTextureManager(), oreDictStacks.get(filter).renderStack, 59, yStart + 3); - GL11.glDisable(GL11.GL_LIGHTING); - GL11.glPopMatrix(); - } catch(Exception e) {} - } + if( itemFilter.materialItem != null ) + { + GL11.glPushMatrix(); + GL11.glEnable( GL11.GL_LIGHTING ); + itemRender.renderItemAndEffectIntoGUI( fontRendererObj, mc.getTextureManager(), itemFilter.materialItem, 59, + yStart + 3 ); + GL11.glDisable( GL11.GL_LIGHTING ); + GL11.glPopMatrix(); + } - fontRendererObj.drawString(MekanismUtils.localize("gui.oredictFilter"), 78, yStart + 2, 0x404040); - fontRendererObj.drawString(filter.color != null ? filter.color.getName() : MekanismUtils.localize("gui.none"), 78, yStart + 11, 0x404040); - } - else if(filter instanceof TMaterialFilter) - { - TMaterialFilter itemFilter = (TMaterialFilter)filter; + fontRendererObj.drawString( MekanismUtils.localize( "gui.materialFilter" ), 78, yStart + 2, 0x404040 ); + fontRendererObj.drawString( filter.color != null ? filter.color.getName() : MekanismUtils.localize( "gui.none" ), 78, + yStart + 11, 0x404040 ); + } + else + if( filter instanceof TModIDFilter ) + { + final TModIDFilter modFilter = (TModIDFilter)filter; - if(itemFilter.materialItem != null) - { - GL11.glPushMatrix(); - GL11.glEnable(GL11.GL_LIGHTING); - itemRender.renderItemAndEffectIntoGUI(fontRendererObj, mc.getTextureManager(), itemFilter.materialItem, 59, yStart + 3); - GL11.glDisable(GL11.GL_LIGHTING); - GL11.glPopMatrix(); - } + if( !modIDStacks.containsKey( modFilter ) ) + updateStackList( modFilter ); - fontRendererObj.drawString(MekanismUtils.localize("gui.materialFilter"), 78, yStart + 2, 0x404040); - fontRendererObj.drawString(filter.color != null ? filter.color.getName() : MekanismUtils.localize("gui.none"), 78, yStart + 11, 0x404040); - } - else if(filter instanceof TModIDFilter) - { - TModIDFilter modFilter = (TModIDFilter)filter; + if( modIDStacks.get( filter ).renderStack != null ) + try + { + GL11.glPushMatrix(); + GL11.glEnable( GL11.GL_LIGHTING ); + itemRender.renderItemAndEffectIntoGUI( fontRendererObj, mc.getTextureManager(), + modIDStacks.get( filter ).renderStack, 59, yStart + 3 ); + GL11.glDisable( GL11.GL_LIGHTING ); + GL11.glPopMatrix(); + } + catch( final Exception e ) + {} - if(!modIDStacks.containsKey(modFilter)) - { - updateStackList(modFilter); - } + fontRendererObj.drawString( MekanismUtils.localize( "gui.modIDFilter" ), 78, yStart + 2, 0x404040 ); + fontRendererObj.drawString( filter.color != null ? filter.color.getName() : MekanismUtils.localize( "gui.none" ), 78, + yStart + 11, 0x404040 ); + } - if(modIDStacks.get(filter).renderStack != null) - { - try { - GL11.glPushMatrix(); - GL11.glEnable(GL11.GL_LIGHTING); - itemRender.renderItemAndEffectIntoGUI(fontRendererObj, mc.getTextureManager(), modIDStacks.get(filter).renderStack, 59, yStart + 3); - GL11.glDisable(GL11.GL_LIGHTING); - GL11.glPopMatrix(); - } catch(Exception e) {} - } - - fontRendererObj.drawString(MekanismUtils.localize("gui.modIDFilter"), 78, yStart + 2, 0x404040); - fontRendererObj.drawString(filter.color != null ? filter.color.getName() : MekanismUtils.localize("gui.none"), 78, yStart + 11, 0x404040); - } + // Draw hovertext for sorting buttons + final int arrowX = filterX + filterW - 12; + if( getFilterIndex() + i > 0 ) + if( xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 14 && yAxis <= yStart + 20 ) + drawCreativeTabHoveringText( MekanismUtils.localize( "gui.moveUp" ), xAxis, yAxis ); + if( getFilterIndex() + i < tileEntity.filters.size() - 1 ) + if( xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 21 && yAxis <= yStart + 27 ) + drawCreativeTabHoveringText( MekanismUtils.localize( "gui.moveDown" ), xAxis, yAxis ); } - } - if(tileEntity.color != null) + if( tileEntity.color != null ) { GL11.glPushMatrix(); - GL11.glColor4f(1, 1, 1, 1); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glEnable(GL12.GL_RESCALE_NORMAL); + GL11.glColor4f( 1, 1, 1, 1 ); + GL11.glEnable( GL11.GL_LIGHTING ); + GL11.glEnable( GL12.GL_RESCALE_NORMAL ); - mc.getTextureManager().bindTexture(MekanismRenderer.getBlocksTexture()); - itemRender.renderIcon(13, 137, MekanismRenderer.getColorIcon(tileEntity.color), 16, 16); + mc.getTextureManager().bindTexture( MekanismRenderer.getBlocksTexture() ); + itemRender.renderIcon( 13, 137, MekanismRenderer.getColorIcon( tileEntity.color ), 16, 16 ); - GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable( GL11.GL_LIGHTING ); GL11.glPopMatrix(); } - if(xAxis >= 13 && xAxis <= 29 && yAxis >= 137 && yAxis <= 153) - { - if(tileEntity.color != null) - { - drawCreativeTabHoveringText(tileEntity.color.getName(), xAxis, yAxis); - } - else { - drawCreativeTabHoveringText(MekanismUtils.localize("gui.none"), xAxis, yAxis); - } - } + // Draw tooltips for buttons + if( xAxis >= 13 && xAxis <= 29 && yAxis >= 137 && yAxis <= 153 ) + if( tileEntity.color != null ) + drawCreativeTabHoveringText( tileEntity.color.getName(), xAxis, yAxis ); + else + drawCreativeTabHoveringText( MekanismUtils.localize( "gui.none" ), xAxis, yAxis ); - if(xAxis >= 12 && xAxis <= 26 && yAxis >= 110 && yAxis <= 124) - { - drawCreativeTabHoveringText(MekanismUtils.localize("gui.autoEject"), xAxis, yAxis); - } + if( xAxis >= 12 && xAxis <= 26 && yAxis >= 110 && yAxis <= 124 ) + drawCreativeTabHoveringText( MekanismUtils.localize( "gui.autoEject" ), xAxis, yAxis ); - if(xAxis >= 12 && xAxis <= 26 && yAxis >= 84 && yAxis <= 98) - { - drawCreativeTabHoveringText(MekanismUtils.localize("gui.logisticalSorter.roundRobin"), xAxis, yAxis); - } + if( xAxis >= 12 && xAxis <= 26 && yAxis >= 84 && yAxis <= 98 ) + drawCreativeTabHoveringText( MekanismUtils.localize( "gui.logisticalSorter.roundRobin" ), xAxis, yAxis ); - super.drawGuiContainerForegroundLayer(mouseX, mouseY); + super.drawGuiContainerForegroundLayer( mouseX, mouseY ); } @Override - protected void drawGuiContainerBackgroundLayer(float partialTick, int mouseX, int mouseY) + protected void drawGuiContainerBackgroundLayer( float partialTick, int mouseX, int mouseY ) { - super.drawGuiContainerBackgroundLayer(partialTick, mouseX, mouseY); + super.drawGuiContainerBackgroundLayer( partialTick, mouseX, mouseY ); - mc.renderEngine.bindTexture(MekanismUtils.getResource(ResourceType.GUI, "GuiLogisticalSorter.png")); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - int guiWidth = (width - xSize) / 2; - int guiHeight = (height - ySize) / 2; - drawTexturedModalRect(guiWidth, guiHeight, 0, 0, xSize, ySize); + // Draw main gui background + mc.renderEngine.bindTexture( MekanismUtils.getResource( ResourceType.GUI, "GuiLogisticalSorter.png" ) ); + GL11.glColor4f( 1.0F, 1.0F, 1.0F, 1.0F ); + drawTexturedModalRect( guiLeft, guiTop, 0, 0, xSize, ySize ); - drawTexturedModalRect(guiWidth + 154, guiHeight + 18 + getScroll(), 232, 0, 12, 15); + // Draw scrollbar + drawTexturedModalRect( guiLeft + scrollX, guiTop + scrollY + getScroll(), 232 + ( needsScrollBars() ? 0 : 12 ), 0, 12, 15 ); - int xAxis = (mouseX - (width - xSize) / 2); - int yAxis = (mouseY - (height - ySize) / 2); + // Get mouse position relative to gui + final int xAxis = mouseX - guiLeft; + final int yAxis = mouseY - guiTop; - for(int i = 0; i < 4; i++) - { - if(tileEntity.filters.get(getFilterIndex()+i) != null) + // Draw filter backgrounds + for( int i = 0; i < 4; i++ ) + if( tileEntity.filters.get( getFilterIndex() + i ) != null ) { - TransporterFilter filter = tileEntity.filters.get(getFilterIndex()+i); - int yStart = i*29 + 18; + final TransporterFilter filter = tileEntity.filters.get( getFilterIndex() + i ); + final int yStart = i * filterH + filterY; - boolean mouseOver = xAxis >= 56 && xAxis <= 152 && yAxis >= yStart && yAxis <= yStart+29; + // Flag for mouse over this filter + boolean mouseOver = xAxis >= filterX && xAxis <= filterX + filterW && yAxis >= yStart && yAxis <= yStart + filterH; - if(filter instanceof TItemStackFilter) - { - MekanismRenderer.color(EnumColor.INDIGO, 1.0F, 2.5F); - } - else if(filter instanceof TOreDictFilter) - { - MekanismRenderer.color(EnumColor.BRIGHT_GREEN, 1.0F, 2.5F); - } - else if(filter instanceof TMaterialFilter) - { - MekanismRenderer.color(EnumColor.PURPLE, 1.0F, 4F); - } - else if(filter instanceof TModIDFilter) - { - MekanismRenderer.color(EnumColor.PINK, 1.0F, 2.5F); - } - - drawTexturedModalRect(guiWidth + 56, guiHeight + yStart, mouseOver ? 0 : 96, 166, 96, 29); + // Change colour based on filter type + if( filter instanceof TItemStackFilter ) + MekanismRenderer.color( EnumColor.INDIGO, 1.0F, 2.5F ); + else + if( filter instanceof TOreDictFilter ) + MekanismRenderer.color( EnumColor.BRIGHT_GREEN, 1.0F, 2.5F ); + else + if( filter instanceof TMaterialFilter ) + MekanismRenderer.color( EnumColor.PURPLE, 1.0F, 4F ); + else + if( filter instanceof TModIDFilter ) + MekanismRenderer.color( EnumColor.PINK, 1.0F, 2.5F ); + + drawTexturedModalRect( guiLeft + filterX, guiTop + yStart, mouseOver ? 0 : filterW, 166, filterW, filterH ); MekanismRenderer.resetColor(); + + // Draw sort buttons + final int arrowX = filterX + filterW - 12; + if( getFilterIndex() + i > 0 ) + { + mouseOver = xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 14 && yAxis <= yStart + 20; + drawTexturedModalRect( guiLeft + arrowX, guiTop + yStart + 14, 190, mouseOver ? 143 : 115, 11, 7 ); + } + if( getFilterIndex() + i < tileEntity.filters.size() - 1 ) + { + mouseOver = xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 21 && yAxis <= yStart + 27; + drawTexturedModalRect( guiLeft + arrowX, guiTop + yStart + 21, 190, mouseOver ? 157 : 129, 11, 7 ); + } } - } - if(xAxis >= 12 && xAxis <= 26 && yAxis >= 110 && yAxis <= 124) - { - drawTexturedModalRect(guiWidth + 12, guiHeight + 110, 176, 0, 14, 14); - } - else { - drawTexturedModalRect(guiWidth + 12, guiHeight + 110, 176, 14, 14, 14); - } + // Draw gui buttons + if( xAxis >= 12 && xAxis <= 26 && yAxis >= 110 && yAxis <= 124 ) + drawTexturedModalRect( guiLeft + 12, guiTop + 110, 176, 0, 14, 14 ); + else + drawTexturedModalRect( guiLeft + 12, guiTop + 110, 176, 14, 14, 14 ); - if(xAxis >= 12 && xAxis <= 26 && yAxis >= 84 && yAxis <= 98) - { - drawTexturedModalRect(guiWidth + 12, guiHeight + 84, 176 + 14, 0, 14, 14); - } - else { - drawTexturedModalRect(guiWidth + 12, guiHeight + 84, 176 + 14, 14, 14, 14); - } + if( xAxis >= 12 && xAxis <= 26 && yAxis >= 84 && yAxis <= 98 ) + drawTexturedModalRect( guiLeft + 12, guiTop + 84, 176 + 14, 0, 14, 14 ); + else + drawTexturedModalRect( guiLeft + 12, guiTop + 84, 176 + 14, 14, 14, 14 ); } - private void updateStackList(TOreDictFilter filter) + private void updateStackList( TOreDictFilter filter ) { - if(!oreDictStacks.containsKey(filter)) - { - oreDictStacks.put(filter, new StackData()); - } - - oreDictStacks.get(filter).iterStacks = OreDictCache.getOreDictStacks(filter.oreDictName, false); + if( !oreDictStacks.containsKey( filter ) ) + oreDictStacks.put( filter, new StackData() ); + + oreDictStacks.get( filter ).iterStacks = OreDictCache.getOreDictStacks( filter.oreDictName, false ); stackSwitch = 0; updateScreen(); - oreDictStacks.get(filter).stackIndex = -1; + oreDictStacks.get( filter ).stackIndex = -1; } - - private void updateStackList(TModIDFilter filter) + + private void updateStackList( TModIDFilter filter ) { - if(!modIDStacks.containsKey(filter)) - { - modIDStacks.put(filter, new StackData()); - } - - modIDStacks.get(filter).iterStacks = OreDictCache.getModIDStacks(filter.modID, false); + if( !modIDStacks.containsKey( filter ) ) + modIDStacks.put( filter, new StackData() ); + + modIDStacks.get( filter ).iterStacks = OreDictCache.getModIDStacks( filter.modID, false ); stackSwitch = 0; updateScreen(); - modIDStacks.get(filter).stackIndex = -1; + modIDStacks.get( filter ).stackIndex = -1; } public static class StackData { - public List iterStacks; - public int stackIndex; - public ItemStack renderStack; + public List< ItemStack > iterStacks; + public int stackIndex; + public ItemStack renderStack; + } + + /** + * returns true if there are more filters than can fit in the gui + */ + private boolean needsScrollBars() + { + return tileEntity.filters.size() > 4; } } \ No newline at end of file diff --git a/src/main/resources/assets/mekanism/gui/GuiLogisticalSorter.png b/src/main/resources/assets/mekanism/gui/GuiLogisticalSorter.png index 219c0385e214cf74e740165feba7d3d2c1edd10a..229a91541008d86a5e538677a5ec7635e2392842 100644 GIT binary patch literal 2519 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 literal 4812 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 Date: Sun, 5 Apr 2015 23:03:56 +1000 Subject: [PATCH 2/3] Sorting buttons now work Got the sorting buttons to work. Clicking on the arrow buttons on a filter panel will now move that filter up or down in the filter list. Without having made any changed to how filters are processed, filters higher in the list will naturally be processed before later filters, thereby making it like a priority system. For example, if an item matches two filters, the higher priority filter will take that item before the lower filter, in that way seperating a specific item from a broader (wildcard) specified filter. --- .../client/gui/GuiLogisticalSorter.java | 16 ++++++++++++++ src/main/java/mekanism/common/HashList.java | 15 +++++++++++++ .../tile/TileEntityLogisticalSorter.java | 21 +++++++++++++++---- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/main/java/mekanism/client/gui/GuiLogisticalSorter.java b/src/main/java/mekanism/client/gui/GuiLogisticalSorter.java index 12be32088..c923768d0 100644 --- a/src/main/java/mekanism/client/gui/GuiLogisticalSorter.java +++ b/src/main/java/mekanism/client/gui/GuiLogisticalSorter.java @@ -210,12 +210,28 @@ public class GuiLogisticalSorter extends GuiMekanism final int arrowX = filterX + filterW - 12; if( getFilterIndex() + i > 0 ) if( xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 14 && yAxis <= yStart + 20 ) + { // Process up button click + final ArrayList data = new ArrayList(); + data.add( 3 ); + data.add( getFilterIndex() + i ); + + Mekanism.packetHandler.sendToServer( new TileEntityMessage( Coord4D.get( tileEntity ), data ) ); + SoundHandler.playSound( "gui.button.press" ); return; + } if( getFilterIndex() + i < tileEntity.filters.size() - 1 ) if( xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 21 && yAxis <= yStart + 27 ) + { // Process down button click + final ArrayList data = new ArrayList(); + data.add( 4 ); + data.add( getFilterIndex() + i ); + + Mekanism.packetHandler.sendToServer( new TileEntityMessage( Coord4D.get( tileEntity ), data ) ); + SoundHandler.playSound( "gui.button.press" ); return; + } final TransporterFilter filter = tileEntity.filters.get( getFilterIndex() + i ); diff --git a/src/main/java/mekanism/common/HashList.java b/src/main/java/mekanism/common/HashList.java index 3c100f242..6d9305850 100644 --- a/src/main/java/mekanism/common/HashList.java +++ b/src/main/java/mekanism/common/HashList.java @@ -3,6 +3,8 @@ package mekanism.common; import java.util.ArrayList; import java.util.Iterator; +import mekanism.common.content.transporter.TransporterFilter; + public class HashList implements Iterable { private ArrayList list = new ArrayList(256); @@ -90,6 +92,19 @@ public class HashList implements Iterable { return list.size(); } + + public void swap( int source, int target ) + { + // Make sure both source and target ar legal values + if( source == target ) return; + if( source < 0 || target < 0 ) return; + if( source >= list.size() || target >= list.size() ) return; + + // Perform swap + T temp = list.get( source ); + list.set( source, list.get( target ) ); + list.set( target, temp ); + } @Override public int hashCode() diff --git a/src/main/java/mekanism/common/tile/TileEntityLogisticalSorter.java b/src/main/java/mekanism/common/tile/TileEntityLogisticalSorter.java index ce1677d40..43b5d0aed 100644 --- a/src/main/java/mekanism/common/tile/TileEntityLogisticalSorter.java +++ b/src/main/java/mekanism/common/tile/TileEntityLogisticalSorter.java @@ -3,6 +3,8 @@ package mekanism.common.tile; import java.util.ArrayList; import java.util.EnumSet; +import com.sun.media.jfxmedia.logging.Logger; + import mekanism.api.Coord4D; import mekanism.api.EnumColor; import mekanism.api.IFilterAccess; @@ -23,7 +25,6 @@ import mekanism.common.network.PacketTileEntity.TileEntityMessage; import mekanism.common.util.InventoryUtils; import mekanism.common.util.MekanismUtils; import mekanism.common.util.TransporterUtils; - import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.IInventory; @@ -33,7 +34,6 @@ import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.ForgeDirection; - import io.netty.buffer.ByteBuf; public class TileEntityLogisticalSorter extends TileEntityElectricBlock implements IRedstoneControl, IActiveState, IFilterAccess, ISustainedData @@ -292,7 +292,20 @@ public class TileEntityLogisticalSorter extends TileEntityElectricBlock implemen roundRobin = !roundRobin; rrIndex = 0; } - + else if(type == 3) + { + // Move filter up + int filterIndex = dataStream.readInt(); + filters.swap( filterIndex, filterIndex - 1 ); + openInventory(); + } + else if(type == 4) + { + // Move filter down + int filterIndex = dataStream.readInt(); + filters.swap( filterIndex, filterIndex + 1 ); + openInventory(); + } return; } @@ -461,7 +474,7 @@ public class TileEntityLogisticalSorter extends TileEntityElectricBlock implemen return stack; } - + @Override public boolean canExtractItem(int slotID, ItemStack itemstack, int side) { From f74acdfca67be1b7ff22cc1b65cee7c458d71597 Mon Sep 17 00:00:00 2001 From: TehStoneMan Date: Mon, 6 Apr 2015 11:38:21 +1000 Subject: [PATCH 3/3] Updated Digital Miner GUI Updates to the Digital Miner config GUI to match changes to Logistical Sorter GUI --- .../client/gui/GuiDigitalMinerConfig.java | 103 ++++++++++++++++-- .../common/tile/TileEntityDigitalMiner.java | 14 +++ .../mekanism/gui/GuiDigitalMinerConfig.png | Bin 4836 -> 2623 bytes .../mekanism/gui/GuiDigitalMinerConfig.xcf | Bin 0 -> 24047 bytes 4 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 src/main/resources/assets/mekanism/gui/GuiDigitalMinerConfig.xcf diff --git a/src/main/java/mekanism/client/gui/GuiDigitalMinerConfig.java b/src/main/java/mekanism/client/gui/GuiDigitalMinerConfig.java index 8d0094119..1cc469a85 100644 --- a/src/main/java/mekanism/client/gui/GuiDigitalMinerConfig.java +++ b/src/main/java/mekanism/client/gui/GuiDigitalMinerConfig.java @@ -25,7 +25,6 @@ import mekanism.common.network.PacketTileEntity.TileEntityMessage; import mekanism.common.tile.TileEntityDigitalMiner; import mekanism.common.util.MekanismUtils; import mekanism.common.util.MekanismUtils.ResourceType; - import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiTextField; import net.minecraft.entity.player.EntityPlayer; @@ -34,6 +33,7 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; @SideOnly(Side.CLIENT) @@ -43,6 +43,18 @@ public class GuiDigitalMinerConfig extends GuiMekanism public boolean isDragging = false; + // Scrollbar dimensions + private final int scrollX = 154; + private final int scrollY = 18; + private final int scrollW = 12; + private final int scrollH = 138; + + // Filter dimensions + private final int filterX = 56; + private final int filterY = 18; + private final int filterW = 96; + private final int filterH = 29; + public int dragOffset = 0; public int stackSwitch = 0; @@ -69,12 +81,12 @@ public class GuiDigitalMinerConfig extends GuiMekanism public int getFilterIndex() { - if(tileEntity.filters.size() <= 4) + if( needsScrollBars() ) { - return 0; + final int scrollSize = tileEntity.filters.size() - 4; + return (int)( ( scrollSize + 0.5 ) * scroll ); } - - return (int)((tileEntity.filters.size()*scroll) - ((4F/(float)tileEntity.filters.size()))*scroll); + return 0; } @Override @@ -197,7 +209,7 @@ public class GuiDigitalMinerConfig extends GuiMekanism if(xAxis >= 154 && xAxis <= 166 && yAxis >= getScroll()+18 && yAxis <= getScroll()+18+15) { - if(tileEntity.filters.size()>4) + if( needsScrollBars() ) { dragOffset = yAxis - (getScroll()+18); isDragging = true; @@ -213,6 +225,33 @@ public class GuiDigitalMinerConfig extends GuiMekanism { int yStart = i*29 + 18; + // Check for sorting button + final int arrowX = filterX + filterW - 12; + if( getFilterIndex() + i > 0 ) + if( xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 14 && yAxis <= yStart + 20 ) + { + // Process up button click + final ArrayList data = new ArrayList(); + data.add( 11 ); + data.add( getFilterIndex() + i ); + + Mekanism.packetHandler.sendToServer( new TileEntityMessage( Coord4D.get( tileEntity ), data ) ); + SoundHandler.playSound( "gui.button.press" ); + return; + } + if( getFilterIndex() + i < tileEntity.filters.size() - 1 ) + if( xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 21 && yAxis <= yStart + 27 ) + { + // Process down button click + final ArrayList data = new ArrayList(); + data.add( 12 ); + data.add( getFilterIndex() + i ); + + Mekanism.packetHandler.sendToServer( new TileEntityMessage( Coord4D.get( tileEntity ), data ) ); + SoundHandler.playSound( "gui.button.press" ); + return; + } + if(xAxis >= 56 && xAxis <= 152 && yAxis >= yStart && yAxis <= yStart+29) { MinerFilter filter = tileEntity.filters.get(getFilterIndex()+i); @@ -302,6 +341,35 @@ public class GuiDigitalMinerConfig extends GuiMekanism } } + /** + * Handles mouse input. + */ + @Override + public void handleMouseInput() + { + super.handleMouseInput(); + int i = Mouse.getEventDWheel(); + + if( i != 0 && needsScrollBars() ) + { + final int j = tileEntity.filters.size() - 4; + + if( i > 0 ) + i = 1; + + if( i < 0 ) + i = -1; + + scroll = (float)( scroll - (double)i / (double)j ); + + if( scroll < 0.0F ) + scroll = 0.0F; + + if( scroll > 1.0F ) + scroll = 1.0F; + } + } + @Override public void initGui() { @@ -463,7 +531,7 @@ public class GuiDigitalMinerConfig extends GuiMekanism int guiHeight = (height - ySize) / 2; drawTexturedModalRect(guiWidth, guiHeight, 0, 0, xSize, ySize); - drawTexturedModalRect(guiWidth + 154, guiHeight + 18 + getScroll(), 232, 0, 12, 15); + drawTexturedModalRect( guiLeft + scrollX, guiTop + scrollY + getScroll(), 232 + ( needsScrollBars() ? 0 : 12 ), 0, 12, 15 ); int xAxis = (mouseX - (width - xSize) / 2); int yAxis = (mouseY - (height - ySize) / 2); @@ -496,6 +564,19 @@ public class GuiDigitalMinerConfig extends GuiMekanism drawTexturedModalRect(guiWidth + 56, guiHeight + yStart, mouseOver ? 0 : 96, 166, 96, 29); MekanismRenderer.resetColor(); + + // Draw sort buttons + final int arrowX = filterX + filterW - 12; + if( getFilterIndex() + i > 0 ) + { + mouseOver = xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 14 && yAxis <= yStart + 20; + drawTexturedModalRect( guiLeft + arrowX, guiTop + yStart + 14, 190, mouseOver ? 143 : 115, 11, 7 ); + } + if( getFilterIndex() + i < tileEntity.filters.size() - 1 ) + { + mouseOver = xAxis >= arrowX && xAxis <= arrowX + 10 && yAxis >= yStart + 21 && yAxis <= yStart + 27; + drawTexturedModalRect( guiLeft + arrowX, guiTop + yStart + 21, 190, mouseOver ? 157 : 129, 11, 7 ); + } } } @@ -658,4 +739,12 @@ public class GuiDigitalMinerConfig extends GuiMekanism public int stackIndex; public ItemStack renderStack; } + + /** + * returns true if there are more filters than can fit in the gui + */ + private boolean needsScrollBars() + { + return tileEntity.filters.size() > 4; + } } diff --git a/src/main/java/mekanism/common/tile/TileEntityDigitalMiner.java b/src/main/java/mekanism/common/tile/TileEntityDigitalMiner.java index 62d6618c6..750469e16 100644 --- a/src/main/java/mekanism/common/tile/TileEntityDigitalMiner.java +++ b/src/main/java/mekanism/common/tile/TileEntityDigitalMiner.java @@ -741,6 +741,20 @@ public class TileEntityDigitalMiner extends TileEntityElectricBlock implements I { inverse = !inverse; } + else if(type == 11) + { + // Move filter up + int filterIndex = dataStream.readInt(); + filters.swap( filterIndex, filterIndex - 1 ); + openInventory(); + } + else if(type == 12) + { + // Move filter down + int filterIndex = dataStream.readInt(); + filters.swap( filterIndex, filterIndex + 1 ); + openInventory(); + } MekanismUtils.saveChunk(this); diff --git a/src/main/resources/assets/mekanism/gui/GuiDigitalMinerConfig.png b/src/main/resources/assets/mekanism/gui/GuiDigitalMinerConfig.png index bc6c516fe0e7fb65708d7c8fae6c0bbbd53f5253..eadb5f8f125434deeb4f8786fbb8afb83abca201 100644 GIT binary patch literal 2623 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 literal 4836 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 diff --git a/src/main/resources/assets/mekanism/gui/GuiDigitalMinerConfig.xcf b/src/main/resources/assets/mekanism/gui/GuiDigitalMinerConfig.xcf new file mode 100644 index 0000000000000000000000000000000000000000..003e71d63bacb12b2b154e6d6a3ea29a4cfec921 GIT binary patch literal 24047 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 JU`JhG{|8k(xlaH9 literal 0 HcmV?d00001