From 8dbbea7b6d6938a6fa85a41a84a2f0b5a0d5e345 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 6 Feb 2024 19:00:57 +0300 Subject: [PATCH] InventoryView update --- src/frontend/InventoryView.cpp | 234 ++++++++++++++------------------- src/frontend/InventoryView.h | 220 +++++++++++++------------------ src/frontend/hud.cpp | 66 +++------- 3 files changed, 211 insertions(+), 309 deletions(-) diff --git a/src/frontend/InventoryView.cpp b/src/frontend/InventoryView.cpp index 00db92b0..9ef101c9 100644 --- a/src/frontend/InventoryView.cpp +++ b/src/frontend/InventoryView.cpp @@ -19,65 +19,34 @@ #include "../maths/voxmaths.h" #include "../objects/Player.h" #include "../voxels/Block.h" +#include "../frontend/gui/panels.h" #include "../frontend/gui/controls.h" #include "../util/stringutil.h" - -InventoryLayout::InventoryLayout(glm::vec2 size) : size(size) {} - -void InventoryLayout::add(SlotLayout slot) { - slots.push_back(slot); -} - -void InventoryLayout::add(InventoryPanel panel) { - panels.push_back(panel); -} - -void InventoryLayout::setSize(glm::vec2 size) { - this->size = size; -} - -void InventoryLayout::setOrigin(glm::vec2 origin) { - this->origin = origin; -} - -glm::vec2 InventoryLayout::getSize() const { - return size; -} - -glm::vec2 InventoryLayout::getOrigin() const { - return origin; -} - -std::vector& InventoryLayout::getSlots() { - return slots; -} - -std::vector& InventoryLayout::getPanels() { - return panels; -} +#include "../world/Level.h" SlotLayout::SlotLayout( + int index, glm::vec2 position, bool background, bool itemSource, itemsharefunc shareFunc, slotcallback rightClick ) - : position(position), + : index(index), + position(position), background(background), itemSource(itemSource), shareFunc(shareFunc), rightClick(rightClick) {} -InventoryPanel::InventoryPanel( - glm::vec2 position, - glm::vec2 size, - glm::vec4 color) - : position(position), size(size), color(color) {} - -InventoryBuilder::InventoryBuilder() - : layout(std::make_unique(glm::vec2())) -{} +InventoryBuilder::InventoryBuilder( + LevelFrontend* frontend, + InventoryInteraction& interaction +) : frontend(frontend), + interaction(interaction) +{ + view = std::make_shared(frontend, interaction); +} void InventoryBuilder::addGrid( int cols, int count, @@ -94,14 +63,20 @@ void InventoryBuilder::addGrid( uint width = cols * (slotSize + interval) - interval + padding*2; uint height = rows * (slotSize + interval) - interval + padding*2; - auto lsize = layout->getSize(); - if (coord.x + width > lsize.x) { - lsize.x = coord.x + width; + glm::vec2 vsize = view->getSize(); + if (coord.x + width > vsize.x) { + vsize.x = coord.x + width; } - if (coord.y + height > lsize.y) { - lsize.y = coord.y + height; + if (coord.y + height > vsize.y) { + vsize.y = coord.y + height; + } + view->setSize(vsize); + + if (addpanel) { + auto panel = std::make_shared(coord, glm::vec2(width, height)); + view->setColor(glm::vec4(0, 0, 0, 0.5f)); + view->add(panel); } - layout->setSize(lsize); for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { @@ -112,59 +87,39 @@ void InventoryBuilder::addGrid( row * (slotSize + interval) + padding ); auto builtSlot = slotLayout; + builtSlot.index = row * cols + col; builtSlot.position = position; - layout->add(builtSlot); + view->addSlot(builtSlot); } } - - if (addpanel) { - add(InventoryPanel( - coord, - glm::vec2(width, height), - glm::vec4(0, 0, 0, 0.5f))); - } } -void InventoryBuilder::add(SlotLayout slotLayout) { - uint width = InventoryView::SLOT_SIZE; - uint height = InventoryView::SLOT_SIZE; - - auto coord = slotLayout.position; - auto lsize = layout->getSize(); - if (coord.x + width > lsize.x) { - lsize.x = coord.x + width; - } - if (coord.y + height > lsize.y) { - lsize.y = coord.y + height; - } - layout->add(slotLayout); +void InventoryBuilder::add(SlotLayout layout) { + view->addSlot(layout); } -void InventoryBuilder::add(InventoryPanel panel) { - layout->add(panel); -} - -std::unique_ptr InventoryBuilder::build() { - return std::unique_ptr(layout.release()); +std::shared_ptr InventoryBuilder::build() { + return view; } SlotView::SlotView( - ItemStack& stack, LevelFrontend* frontend, - InventoryInteraction* interaction, - const Content* content, - SlotLayout layout) - : UINode(glm::vec2(), glm::vec2(InventoryView::SLOT_SIZE)), - frontend(frontend), - interaction(interaction), - content(content), - stack(stack), - layout(layout) { + InventoryInteraction& interaction, + SlotLayout layout +) : UINode(glm::vec2(), glm::vec2(InventoryView::SLOT_SIZE)), + frontend(frontend), + interaction(interaction), + content(frontend->getLevel()->content), + layout(layout) +{ setColor(glm::vec4(0, 0, 0, 0.2f)); } -// performance disaster void SlotView::draw(const GfxContext* pctx, Assets* assets) { + if (bound == nullptr) + throw std::runtime_error("unbound slot"); + ItemStack& stack = *bound; + glm::vec2 coord = calcCoord(); int slotSize = InventoryView::SLOT_SIZE; @@ -250,7 +205,12 @@ bool SlotView::isHighlighted() const { } void SlotView::clicked(gui::GUI* gui, int button) { - ItemStack& grabbed = interaction->getGrabbedItem(); + if (bound == nullptr) + throw std::runtime_error("unbound slot"); + + ItemStack& grabbed = interaction.getGrabbedItem(); + ItemStack& stack = *bound; + if (button == mousecode::BUTTON_1) { if (Events::pressed(keycode::LEFT_SHIFT)) { if (layout.shareFunc) { @@ -302,42 +262,56 @@ void SlotView::focus(gui::GUI* gui) { clicked(gui, 0); } +void SlotView::bind(ItemStack& stack) { + bound = &stack; +} + +const SlotLayout& SlotView::getLayout() const { + return layout; +} + InventoryView::InventoryView( - const Content* content, LevelFrontend* frontend, - InventoryInteraction* interaction, - std::shared_ptr inventory, - std::unique_ptr layout) - : Container(glm::vec2(), glm::vec2()), - content(content), - indices(content->getIndices()), - inventory(inventory), - layout(std::move(layout)), - frontend(frontend), - interaction(interaction) { - setSize(this->layout->getSize()); + InventoryInteraction& interaction +) : Container(glm::vec2(), glm::vec2()), + frontend(frontend), + interaction(interaction) +{ + content = frontend->getLevel()->content; + indices = content->getIndices(); setColor(glm::vec4(0, 0, 0, 0.0f)); } InventoryView::~InventoryView() {} -void InventoryView::build() { - size_t index = 0; - for (auto& slot : layout->getSlots()) { - if (index >= inventory->size()) - break; - ItemStack& item = inventory->getSlot(index); +void InventoryView::addSlot(SlotLayout layout) { + uint width = InventoryView::SLOT_SIZE; + uint height = InventoryView::SLOT_SIZE; - auto view = std::make_shared( - item, frontend, interaction, content, slot - ); - if (!slot.background) { - view->setColor(glm::vec4()); - } - slots.push_back(view.get()); - add(view, slot.position); - index++; + auto coord = layout.position; + auto vsize = getSize(); + if (coord.x + width > vsize.x) { + vsize.x = coord.x + width; + } + if (coord.y + height > vsize.y) { + vsize.y = coord.y + height; + } + + auto slot = std::make_shared( + frontend, interaction, layout + ); + if (!layout.background) { + slot->setColor(glm::vec4()); + } + add(slot, layout.position); + slots.push_back(slot.get()); +} + +void InventoryView::bind(std::shared_ptr inventory) { + this->inventory = inventory; + for (auto slot : slots) { + slot->bind(inventory->getSlot(slot->getLayout().index)); } } @@ -349,27 +323,17 @@ void InventoryView::setSelected(int index) { } void InventoryView::setCoord(glm::vec2 coord) { - Container::setCoord(coord - layout->getOrigin()); + Container::setCoord(coord - origin); +} + +void InventoryView::setOrigin(glm::vec2 origin) { + this->origin = origin; +} + +glm::vec2 InventoryView::getOrigin() const { + return origin; } void InventoryView::setInventory(std::shared_ptr inventory) { this->inventory = inventory; } - -InventoryLayout* InventoryView::getLayout() const { - return layout.get(); -} - -void InventoryView::drawBackground(const GfxContext* pctx, Assets* assets) { - glm::vec2 coord = calcCoord(); - auto batch = pctx->getBatch2D(); - - batch->texture(nullptr); - - for (auto& panel : layout->getPanels()) { - glm::vec2 size = panel.size; - glm::vec2 pos = coord + panel.position; - batch->color = panel.color; - batch->rect(pos.x-1, pos.y-1, size.x+2, size.y+2); - } -} diff --git a/src/frontend/InventoryView.h b/src/frontend/InventoryView.h index 9b9e01b4..ff6fc7cc 100644 --- a/src/frontend/InventoryView.h +++ b/src/frontend/InventoryView.h @@ -18,133 +18,8 @@ class ContentIndices; class LevelFrontend; class Inventory; -typedef std::function itemsharefunc; -typedef std::function slotcallback; - -class InventoryInteraction; - -struct SlotLayout { - glm::vec2 position; - bool background; - bool itemSource; - itemsharefunc shareFunc; - slotcallback rightClick; - - SlotLayout(glm::vec2 position, - bool background, - bool itemSource, - itemsharefunc shareFunc, - slotcallback rightClick); -}; - -// temporary unused -struct InventoryPanel { - glm::vec2 position; - glm::vec2 size; - glm::vec4 color; - - InventoryPanel(glm::vec2 position, - glm::vec2 size, - glm::vec4 color); -}; - -class InventoryLayout { - glm::vec2 size {}; - glm::vec2 origin {}; - std::vector slots; - std::vector panels; -public: - InventoryLayout(glm::vec2 size); - - void add(SlotLayout slot); - void add(InventoryPanel panel); - void setSize(glm::vec2 size); - void setOrigin(glm::vec2 origin); - - glm::vec2 getSize() const; - glm::vec2 getOrigin() const; - - std::vector& getSlots(); - std::vector& getPanels(); -}; - -class InventoryBuilder { - std::unique_ptr layout; -public: - InventoryBuilder(); - - void addGrid( - int cols, int count, - glm::vec2 coord, - int padding, - bool addpanel, - SlotLayout slotLayout); - - void add(SlotLayout slotLayout); - void add(InventoryPanel panel); - - std::unique_ptr build(); -}; - -class SlotView : public gui::UINode { - LevelFrontend* frontend; - InventoryInteraction* interaction; - const Content* const content; - ItemStack& stack; - bool highlighted = false; - - SlotLayout layout; -public: - SlotView(ItemStack& stack, - LevelFrontend* frontend, - InventoryInteraction* interaction, - const Content* content, - SlotLayout layout); - - virtual void draw(const GfxContext* pctx, Assets* assets) override; - - void setHighlighted(bool flag); - bool isHighlighted() const; - - virtual void clicked(gui::GUI*, int) override; - virtual void focus(gui::GUI*) override; -}; - -class InventoryView : public gui::Container { - const Content* content; - const ContentIndices* indices; - - std::shared_ptr inventory; - std::unique_ptr layout; - LevelFrontend* frontend; - InventoryInteraction* interaction; - - std::vector slots; -public: - InventoryView( - const Content* content, - LevelFrontend* frontend, - InventoryInteraction* interaction, - std::shared_ptr inventory, - std::unique_ptr layout); - - virtual ~InventoryView(); - - void build(); - - virtual void drawBackground(const GfxContext* pctx, Assets* assets) override; - - void setInventory(std::shared_ptr inventory); - - virtual void setCoord(glm::vec2 coord) override; - - InventoryLayout* getLayout() const; - - void setSelected(int index); - - static const int SLOT_INTERVAL = 4; - static const int SLOT_SIZE = ITEM_ICON_SIZE; -}; +using itemsharefunc = std::function; +using slotcallback = std::function; class InventoryInteraction { ItemStack grabbedItem; @@ -156,4 +31,95 @@ public: } }; +struct SlotLayout { + int index; + glm::vec2 position; + bool background; + bool itemSource; + itemsharefunc shareFunc; + slotcallback rightClick; + + SlotLayout(int index, + glm::vec2 position, + bool background, + bool itemSource, + itemsharefunc shareFunc, + slotcallback rightClick); +}; + +class SlotView : public gui::UINode { + LevelFrontend* frontend; + InventoryInteraction& interaction; + const Content* const content; + SlotLayout layout; + bool highlighted = false; + + ItemStack* bound = nullptr; +public: + SlotView(LevelFrontend* frontend, + InventoryInteraction& interaction, + SlotLayout layout); + + virtual void draw(const GfxContext* pctx, Assets* assets) override; + + void setHighlighted(bool flag); + bool isHighlighted() const; + + virtual void clicked(gui::GUI*, int) override; + virtual void focus(gui::GUI*) override; + + void bind(ItemStack& stack); + + const SlotLayout& getLayout() const; +}; + +class InventoryView : public gui::Container { + const Content* content; + const ContentIndices* indices; + + std::shared_ptr inventory; + LevelFrontend* frontend; + InventoryInteraction& interaction; + + std::vector slots; + glm::vec2 origin {}; +public: + InventoryView(LevelFrontend* frontend, InventoryInteraction& interaction); + virtual ~InventoryView(); + + void setInventory(std::shared_ptr inventory); + + virtual void setCoord(glm::vec2 coord) override; + + void setOrigin(glm::vec2 origin); + glm::vec2 getOrigin() const; + + void setSelected(int index); + + void bind(std::shared_ptr inventory); + + void addSlot(SlotLayout layout); + + static const int SLOT_INTERVAL = 4; + static const int SLOT_SIZE = ITEM_ICON_SIZE; +}; + +class InventoryBuilder { + std::shared_ptr view; + LevelFrontend* frontend; + InventoryInteraction& interaction; +public: + InventoryBuilder(LevelFrontend* frontend, InventoryInteraction& interaction); + + void addGrid( + int cols, int count, + glm::vec2 coord, + int padding, + bool addpanel, + SlotLayout slotLayout); + + void add(SlotLayout slotLayout); + std::shared_ptr build(); +}; + #endif // FRONTEND_INVENTORY_VIEW_H_ diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 7707e965..9cb0a87f 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -179,7 +179,7 @@ std::shared_ptr HudRenderer::createContentAccess() { accessInventory->getSlot(id-1).set(ItemStack(id, 1)); } - SlotLayout slotLayout(glm::vec2(), false, true, + SlotLayout slotLayout(-1, glm::vec2(), false, true, [=](ItemStack& item) { auto copy = ItemStack(item); inventory->move(copy, indices); @@ -188,41 +188,25 @@ std::shared_ptr HudRenderer::createContentAccess() { inventory->getSlot(player->getChosenSlot()).set(item); }); - InventoryBuilder builder; + InventoryBuilder builder(frontend, *interaction); builder.addGrid(8, itemsCount-1, glm::vec2(), 8, true, slotLayout); - auto layout = builder.build(); - - auto contentAccess = std::make_shared( - content, - frontend, - interaction.get(), - accessInventory, - std::move(layout) - ); - contentAccess->build(); - return contentAccess; + auto view = builder.build(); + view->bind(accessInventory); + return view; } std::shared_ptr HudRenderer::createHotbar() { auto level = frontend->getLevel(); auto player = level->player; auto inventory = player->getInventory(); - auto content = level->content; - SlotLayout slotLayout(glm::vec2(), false, false, nullptr, nullptr); - InventoryBuilder builder; + SlotLayout slotLayout(-1, glm::vec2(), false, false, nullptr, nullptr); + InventoryBuilder builder(frontend, *interaction); builder.addGrid(10, 10, glm::vec2(), 4, true, slotLayout); - auto layout = builder.build(); + auto view = builder.build(); - layout->setOrigin(glm::vec2(layout->getSize().x/2, 0)); - auto view = std::make_shared( - content, - frontend, - interaction.get(), - inventory, - std::move(layout) - ); - view->build(); + view->setOrigin(glm::vec2(view->getSize().x/2, 0)); + view->bind(inventory); view->setInteractive(false); return view; } @@ -231,24 +215,15 @@ std::shared_ptr HudRenderer::createInventory() { auto level = frontend->getLevel(); auto player = level->player; auto inventory = player->getInventory(); - auto content = level->content; - SlotLayout slotLayout(glm::vec2(), true, false, [=](ItemStack& stack) { + SlotLayout slotLayout(-1, glm::vec2(), true, false, [=](ItemStack& stack) { stack.clear(); }, nullptr); - InventoryBuilder builder; + InventoryBuilder builder(frontend, *interaction); builder.addGrid(10, inventory->size(), glm::vec2(), 4, true, slotLayout); - auto layout = builder.build(); - - auto view = std::make_shared( - content, - frontend, - interaction.get(), - inventory, - std::move(layout) - ); - view->build(); + auto view = builder.build(); + view->bind(inventory); return view; } @@ -261,12 +236,11 @@ HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend) interaction = std::make_unique(); grabbedItemView = std::make_shared( - interaction->getGrabbedItem(), frontend, - interaction.get(), - frontend->getLevel()->content, - SlotLayout(glm::vec2(), false, false, nullptr, nullptr) + *interaction, + SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr) ); + grabbedItemView->bind(interaction->getGrabbedItem()); grabbedItemView->setColor(glm::vec4()); grabbedItemView->setInteractive(false); @@ -417,10 +391,8 @@ void HudRenderer::draw(const GfxContext& ctx){ } if (inventoryOpen) { - auto caLayout = contentAccess->getLayout(); - auto invLayout = inventoryView->getLayout(); - float caWidth = caLayout->getSize().x; - glm::vec2 invSize = invLayout->getSize(); + float caWidth = contentAccess->getSize().x; + glm::vec2 invSize = inventoryView->getSize(); float width = viewport.getWidth();