diff --git a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/DrawableStoreItem.java b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/DrawableStoreItem.java index bf0990b..0e7a0d6 100644 --- a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/DrawableStoreItem.java +++ b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/DrawableStoreItem.java @@ -8,22 +8,30 @@ import net.minecraft.util.Identifier; // All the custom content that a store item will have. Handled by @see MerchandiseScroller.java public class DrawableStoreItem extends ClickableLayer { + // Names are hard. ITEM_ICON is the actual SLOT icon itself; not the in-game item!!!! private static final Identifier ITEM_ICON = new Identifier(Keeblarcraft.MOD_ID, "textures/gui/shopkeeper_item_slot.png"); private Integer itemCost; private String itemName; private Integer amountSelected = 0; public DrawableStoreItem(String itemName, Integer itemCost) { - this(itemName, itemCost, Text.of(""), 0, 0, 0, 0); - + this(itemName, itemCost, Text.of(""), 85, 50); } - public DrawableStoreItem(String itemName, Integer itemCost, Text layerName, int width, int height, int startX, int startY) { - super(ITEM_ICON, layerName, width, height, startX, startY); + public DrawableStoreItem(String itemName, Integer itemCost, Text layerName, int width, int height) { + super(ITEM_ICON, layerName, width, height, 0, 0); this.itemCost = itemCost; this.itemName = itemName; } + public Integer GetPrice() { + return this.itemCost; + } + + public String GetName() { + return this.itemName; + } + public void Add() { ++this.amountSelected; System.out.println("Current buy amount: " + this.amountSelected); diff --git a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/MerchandiseScroller.java b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/MerchandiseScroller.java index 5487179..50e7c00 100644 --- a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/MerchandiseScroller.java +++ b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/MerchandiseScroller.java @@ -3,6 +3,7 @@ package jesse.keeblarcraft.gui.ShopKeeperGUI; import jesse.keeblarcraft.GuiMgr.ShopKeeper.ShopKeeperInventory; import jesse.keeblarcraft.GuiMgr.ShopKeeper.StoreItem; import jesse.keeblarcraft.gui.Generics.ClickableLayer; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -10,21 +11,78 @@ import net.minecraft.util.Identifier; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; // This is the main section in the GUI that will display the stores "merchandise" -- all the items on sale. -public class MerchandiseScroller { +public class MerchandiseScroller extends ClickableLayer { private final ShopKeeperInventory storeInventory; + private int scrollAmount = 0; // Indicator for how many tickets the scrollbar is down + private final int maxDisplayItems = 6; + // Key = item name // Value = the drawable slot for it // The KVP keeps it so duplicate items don't take up more than 1 store slot private final HashMap drawableInventory; + List drawList = new ArrayList(); - public MerchandiseScroller(ShopKeeperInventory storeInventory) { + public MerchandiseScroller(Identifier texture, Text layerName, int width, int height, int startX, int startY, ShopKeeperInventory storeInventory) { + super(texture, layerName, width, height, startX, startY); this.storeInventory = storeInventory; drawableInventory = new HashMap<>(); } + public void UpdateScrollAmount(double amount) { + + this.scrollAmount = (int) Math.floor(amount * 100); +// System.out.println("Scroll amount is: " + scrollAmount + " from " + amount); + } + + @Override + public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) { + // scrollAmount is our indicator for where to start in the list to draw going +6 past it + int drawX = this.getX()+10; + int drawY = this.getY()+5; + int xScalar = 0; + int yScalar = 0; + int oscillator = 0; + +// System.out.println("[Merch]: Store size = " + storeInventory.Size()); +// System.out.println("[Merch]: Draw list size: " + drawList.size()); + for (int i = scrollAmount; i < scrollAmount + maxDisplayItems; i++) { + // Make sure we are within the bounds of the size + if (i < drawList.size()) { + DrawableStoreItem storeItem = drawList.get(i); +// System.out.println("[Merch]: Item found. Name of item: " + storeItem.GetName() + ". Price: " + storeItem.GetPrice()); +// System.out.println("DRAWX DRAWY WIDTH HEIGHT: " + drawX + " " + drawY + " " + storeItem.getWidth() + " " + storeItem.getHeight()); + // uv values can be changed for smooth scrolling in the future; but for now with jar-scrolling we will be + // scrolling at least 1 height value of the store stuff + context.drawTexture(storeItem.GetTexture(), drawX, drawY, 0, 0, storeItem.getWidth(), storeItem.getHeight(), storeItem.getWidth(), storeItem.getHeight()); + + if (oscillator % 2 == 0) { + // Even implies we are going to odd; which means this is xScalar+1 + xScalar++; +// yScalar--; + oscillator++; + } else { + yScalar++; + xScalar--; + oscillator--; + } + + // drawX and drawY must start in top left of grid -> then add a scalar. + // this.getX() + 10 means the MINIMUM spacer is 10 off the X axis + // - width + 15 means spacer is 15 pix * xScalar (first or second in row) + // this.getY() + 5 means the MINIMUM spacer is 5 off the Y axi + // - height + 5 mean 5 pixels between each row +// System.out.println("X Scalar: " + xScalar); +// System.out.println("Y scalar: " + yScalar); + drawX = this.getX() + 10 + ((storeItem.getWidth() + 15) * xScalar); + drawY = this.getY() + 5 + ((storeItem.getHeight() + 5) * yScalar); + } + } + } + public Integer Size() { return storeInventory.Size(); } @@ -32,9 +90,23 @@ public class MerchandiseScroller { public void Add(StoreItem item) { storeInventory.Add(item); drawableInventory.put(item.GetUPC(), new DrawableStoreItem(item.GetName(), item.GetCost())); + ResizeDrawlist(); } public void Remove(String upc) { storeInventory.Remove(upc); + ResizeDrawlist(); } + + private void ResizeDrawlist() { + drawList.clear(); + for (Map.Entry entry : drawableInventory.entrySet()) { + drawList.add(entry.getValue()); + } + + System.out.println("Resized draw list. Size is now " + drawList.size()); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) {} } diff --git a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/Scrollbar.java b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/Scrollbar.java index 9bdc3b2..1c30890 100644 --- a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/Scrollbar.java +++ b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/Scrollbar.java @@ -8,8 +8,10 @@ import net.minecraft.util.Identifier; public class Scrollbar extends ClickableLayer { private boolean isDragging = false; + private boolean isLocked = false; private int scrollbarStart = 0; private int scrollbarEnd = 0; + private double scrollDistance; // The current value of where the bar is between scrollbarEnd and scrollbarStart public Scrollbar(Identifier texture, Text layerName, int width, int height, int startX, int startY, int scrollbarStart, int scrollbarMaxLength) { super(texture, layerName, width, height, startX, startY); @@ -26,11 +28,38 @@ public class Scrollbar extends ClickableLayer { dY = -1.0; } - if (isDragging && mY >= this.scrollbarStart && mY <= this.scrollbarEnd) { + if (isDragging && mY >= this.scrollbarStart && mY <= this.scrollbarEnd && !isLocked) { this.MoveLayer(this.getX(), (int)mY - (this.getHeight() / 2)); + UpdateScrollDistance(mY); } } + public void SetLocked(boolean b) { + this.isLocked = b; + } + + public double GetScrollDistance() { + return this.scrollDistance; + } + + // You must check to make sure mouseY is in between scrollbarEnd and scrollbarStart before calling this or the + // number will be VERY wrong!!! + private void UpdateScrollDistance(double mouseY) { + // We subtract the floor from mouseY to do our math from 0 up + mouseY -= scrollbarStart; + double tmpScrollDistance = (mouseY / (scrollbarEnd - scrollbarStart)); + + // Floating point arithmetic sucks; so this is just bounds-clearing + if (tmpScrollDistance < 0) { + tmpScrollDistance = 0.01; + } else if (tmpScrollDistance > 1) { + tmpScrollDistance = 0.99; + } + this.scrollDistance = tmpScrollDistance; + +// System.out.println("Scrollbar distance: " + scrollDistance); + } + @Override public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { // We intentionally switch the scroll direction since it is backwards @@ -44,8 +73,12 @@ public class Scrollbar extends ClickableLayer { int newY = this.getY() + (int) verticalAmount; System.out.println("Mouse move. newY: " + newY + " -> this.getY()=" + this.getY()); - if (newY >= this.scrollbarStart-12 && newY <= this.scrollbarEnd-9) { + + // For the time being these values are going to stick and feel the best with the scrollbar + // Probably should be fixed in the future so no magic numbers need to exist here. Oh well. + if (newY >= this.scrollbarStart-12 && newY <= this.scrollbarEnd-9 && !isLocked) { this.MoveLayer(this.getX(), newY); + UpdateScrollDistance(newY); } return true; diff --git a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/ShopKeeperMenu.java b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/ShopKeeperMenu.java index 8d36015..86c6a78 100644 --- a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/ShopKeeperMenu.java +++ b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/ShopKeeperMenu.java @@ -3,6 +3,7 @@ package jesse.keeblarcraft.gui.ShopKeeperGUI; import jesse.keeblarcraft.Entities.ShopKeeper; import jesse.keeblarcraft.GuiMgr.ShopKeeper.ShopKeeperHandler; import jesse.keeblarcraft.GuiMgr.ShopKeeper.ShopKeeperInventory; +import jesse.keeblarcraft.GuiMgr.ShopKeeper.StoreItem; import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.ClientHelpers.Helper; import jesse.keeblarcraft.gui.Generics.ClickableLayer; @@ -44,13 +45,47 @@ public class ShopKeeperMenu extends HandledScreen { this.backgroundHeight = 256; this.x = (width - backgroundWidth) / 2; this.y = (height - backgroundHeight) / 2; + + // These value are derived from playing around with GUI placement. A better method probably exists; but not right now! scrollbar = new Scrollbar(SCROLLBAR, Text.of("scrollbar"), 15, 28, x+243, y+40, y+50, 163); // Add all layers below AddNewButton(ADD_BUTTON, Text.of("ADD ITEM BUTTON"), x+20, y+20, 8, 8); AddNewLayer(scrollbar); - catalogue = new MerchandiseScroller(this.getScreenHandler().GetInventory()); + + + + catalogue = new MerchandiseScroller(null, Text.of("catalogue"), 200, 166, x+45, y+44, this.getScreenHandler().GetInventory()); + + + // This is for temporary testing + StoreItem newMerch = new StoreItem("Dirt block", "minecraft:dirt_block", 10000000); + StoreItem newMerch2 = new StoreItem("Dirt block2", "minecraft:dirt_block2", 10000000); + StoreItem newMerch3 = new StoreItem("Dirt block3", "minecraft:dirt_block3", 10000000); + StoreItem newMerch4 = new StoreItem("Dirt block4", "minecraft:dirt_block4", 10000000); + StoreItem newMerch5 = new StoreItem("Dirt block5", "minecraft:dirt_block5", 10000000); + StoreItem newMerch6 = new StoreItem("Dirt block6", "minecraft:dirt_block6", 10000000); + StoreItem newMerch7 = new StoreItem("Dirt block7", "minecraft:dirt_block7", 10000000); + + + catalogue.Add(newMerch); + catalogue.Add(newMerch2); + catalogue.Add(newMerch3); + catalogue.Add(newMerch4); + catalogue.Add(newMerch5); + catalogue.Add(newMerch6); + catalogue.Add(newMerch7); + + + + + + // The GUI can comfortably fit 6 items. If the amount is less; the scrollbar should be disabled from use. + if (catalogue.Size() <= 6) { + scrollbar.SetLocked(true); + } + System.out.println("This store catalogue has size " + catalogue.Size()); } @@ -64,9 +99,12 @@ public class ShopKeeperMenu extends HandledScreen { this.getScreenHandler().showSlot("add_item_menu", "add_item_slot"); - // TODO: Temporary to just prove a point that we can draw item icons in the menu + // TODO: Temporary to just prove a point that we can draw item icons in the menu ItemStack tempStack = Items.ACACIA_DOOR.getDefaultStack(); + catalogue.UpdateScrollAmount(scrollbar.GetScrollDistance()); + catalogue.renderButton(context, mouseX, mouseY, delta); + // Draws primary layers first for (ClickableLayer layer : layers) {