InventoryView update

This commit is contained in:
MihailRis
2024-02-06 19:00:57 +03:00
parent 52e60c979b
commit 8dbbea7b6d
3 changed files with 211 additions and 309 deletions
+99 -135
View File
@@ -19,65 +19,34 @@
#include "../maths/voxmaths.h" #include "../maths/voxmaths.h"
#include "../objects/Player.h" #include "../objects/Player.h"
#include "../voxels/Block.h" #include "../voxels/Block.h"
#include "../frontend/gui/panels.h"
#include "../frontend/gui/controls.h" #include "../frontend/gui/controls.h"
#include "../util/stringutil.h" #include "../util/stringutil.h"
#include "../world/Level.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<SlotLayout>& InventoryLayout::getSlots() {
return slots;
}
std::vector<InventoryPanel>& InventoryLayout::getPanels() {
return panels;
}
SlotLayout::SlotLayout( SlotLayout::SlotLayout(
int index,
glm::vec2 position, glm::vec2 position,
bool background, bool background,
bool itemSource, bool itemSource,
itemsharefunc shareFunc, itemsharefunc shareFunc,
slotcallback rightClick slotcallback rightClick
) )
: position(position), : index(index),
position(position),
background(background), background(background),
itemSource(itemSource), itemSource(itemSource),
shareFunc(shareFunc), shareFunc(shareFunc),
rightClick(rightClick) {} rightClick(rightClick) {}
InventoryPanel::InventoryPanel( InventoryBuilder::InventoryBuilder(
glm::vec2 position, LevelFrontend* frontend,
glm::vec2 size, InventoryInteraction& interaction
glm::vec4 color) ) : frontend(frontend),
: position(position), size(size), color(color) {} interaction(interaction)
{
InventoryBuilder::InventoryBuilder() view = std::make_shared<InventoryView>(frontend, interaction);
: layout(std::make_unique<InventoryLayout>(glm::vec2())) }
{}
void InventoryBuilder::addGrid( void InventoryBuilder::addGrid(
int cols, int count, int cols, int count,
@@ -94,14 +63,20 @@ void InventoryBuilder::addGrid(
uint width = cols * (slotSize + interval) - interval + padding*2; uint width = cols * (slotSize + interval) - interval + padding*2;
uint height = rows * (slotSize + interval) - interval + padding*2; uint height = rows * (slotSize + interval) - interval + padding*2;
auto lsize = layout->getSize(); glm::vec2 vsize = view->getSize();
if (coord.x + width > lsize.x) { if (coord.x + width > vsize.x) {
lsize.x = coord.x + width; vsize.x = coord.x + width;
} }
if (coord.y + height > lsize.y) { if (coord.y + height > vsize.y) {
lsize.y = coord.y + height; vsize.y = coord.y + height;
}
view->setSize(vsize);
if (addpanel) {
auto panel = std::make_shared<gui::Container>(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 row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) { for (int col = 0; col < cols; col++) {
@@ -112,59 +87,39 @@ void InventoryBuilder::addGrid(
row * (slotSize + interval) + padding row * (slotSize + interval) + padding
); );
auto builtSlot = slotLayout; auto builtSlot = slotLayout;
builtSlot.index = row * cols + col;
builtSlot.position = position; 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) { void InventoryBuilder::add(SlotLayout layout) {
uint width = InventoryView::SLOT_SIZE; view->addSlot(layout);
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(InventoryPanel panel) { std::shared_ptr<InventoryView> InventoryBuilder::build() {
layout->add(panel); return view;
}
std::unique_ptr<InventoryLayout> InventoryBuilder::build() {
return std::unique_ptr<InventoryLayout>(layout.release());
} }
SlotView::SlotView( SlotView::SlotView(
ItemStack& stack,
LevelFrontend* frontend, LevelFrontend* frontend,
InventoryInteraction* interaction, InventoryInteraction& interaction,
const Content* content, SlotLayout layout
SlotLayout layout) ) : UINode(glm::vec2(), glm::vec2(InventoryView::SLOT_SIZE)),
: UINode(glm::vec2(), glm::vec2(InventoryView::SLOT_SIZE)), frontend(frontend),
frontend(frontend), interaction(interaction),
interaction(interaction), content(frontend->getLevel()->content),
content(content), layout(layout)
stack(stack), {
layout(layout) {
setColor(glm::vec4(0, 0, 0, 0.2f)); setColor(glm::vec4(0, 0, 0, 0.2f));
} }
// performance disaster
void SlotView::draw(const GfxContext* pctx, Assets* assets) { void SlotView::draw(const GfxContext* pctx, Assets* assets) {
if (bound == nullptr)
throw std::runtime_error("unbound slot");
ItemStack& stack = *bound;
glm::vec2 coord = calcCoord(); glm::vec2 coord = calcCoord();
int slotSize = InventoryView::SLOT_SIZE; int slotSize = InventoryView::SLOT_SIZE;
@@ -250,7 +205,12 @@ bool SlotView::isHighlighted() const {
} }
void SlotView::clicked(gui::GUI* gui, int button) { 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 (button == mousecode::BUTTON_1) {
if (Events::pressed(keycode::LEFT_SHIFT)) { if (Events::pressed(keycode::LEFT_SHIFT)) {
if (layout.shareFunc) { if (layout.shareFunc) {
@@ -302,42 +262,56 @@ void SlotView::focus(gui::GUI* gui) {
clicked(gui, 0); clicked(gui, 0);
} }
void SlotView::bind(ItemStack& stack) {
bound = &stack;
}
const SlotLayout& SlotView::getLayout() const {
return layout;
}
InventoryView::InventoryView( InventoryView::InventoryView(
const Content* content,
LevelFrontend* frontend, LevelFrontend* frontend,
InventoryInteraction* interaction, InventoryInteraction& interaction
std::shared_ptr<Inventory> inventory, ) : Container(glm::vec2(), glm::vec2()),
std::unique_ptr<InventoryLayout> layout) frontend(frontend),
: Container(glm::vec2(), glm::vec2()), interaction(interaction)
content(content), {
indices(content->getIndices()), content = frontend->getLevel()->content;
inventory(inventory), indices = content->getIndices();
layout(std::move(layout)),
frontend(frontend),
interaction(interaction) {
setSize(this->layout->getSize());
setColor(glm::vec4(0, 0, 0, 0.0f)); setColor(glm::vec4(0, 0, 0, 0.0f));
} }
InventoryView::~InventoryView() {} 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<SlotView>( auto coord = layout.position;
item, frontend, interaction, content, slot auto vsize = getSize();
); if (coord.x + width > vsize.x) {
if (!slot.background) { vsize.x = coord.x + width;
view->setColor(glm::vec4()); }
} if (coord.y + height > vsize.y) {
slots.push_back(view.get()); vsize.y = coord.y + height;
add(view, slot.position); }
index++;
auto slot = std::make_shared<SlotView>(
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> 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) { 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> inventory) { void InventoryView::setInventory(std::shared_ptr<Inventory> inventory) {
this->inventory = 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);
}
}
+93 -127
View File
@@ -18,133 +18,8 @@ class ContentIndices;
class LevelFrontend; class LevelFrontend;
class Inventory; class Inventory;
typedef std::function<void(ItemStack&)> itemsharefunc; using itemsharefunc = std::function<void(ItemStack&)>;
typedef std::function<void(ItemStack&, ItemStack&)> slotcallback; using slotcallback = std::function<void(ItemStack&, ItemStack&)>;
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<SlotLayout> slots;
std::vector<InventoryPanel> 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<SlotLayout>& getSlots();
std::vector<InventoryPanel>& getPanels();
};
class InventoryBuilder {
std::unique_ptr<InventoryLayout> 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<InventoryLayout> 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> inventory;
std::unique_ptr<InventoryLayout> layout;
LevelFrontend* frontend;
InventoryInteraction* interaction;
std::vector<SlotView*> slots;
public:
InventoryView(
const Content* content,
LevelFrontend* frontend,
InventoryInteraction* interaction,
std::shared_ptr<Inventory> inventory,
std::unique_ptr<InventoryLayout> layout);
virtual ~InventoryView();
void build();
virtual void drawBackground(const GfxContext* pctx, Assets* assets) override;
void setInventory(std::shared_ptr<Inventory> 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;
};
class InventoryInteraction { class InventoryInteraction {
ItemStack grabbedItem; 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> inventory;
LevelFrontend* frontend;
InventoryInteraction& interaction;
std::vector<SlotView*> slots;
glm::vec2 origin {};
public:
InventoryView(LevelFrontend* frontend, InventoryInteraction& interaction);
virtual ~InventoryView();
void setInventory(std::shared_ptr<Inventory> 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> inventory);
void addSlot(SlotLayout layout);
static const int SLOT_INTERVAL = 4;
static const int SLOT_SIZE = ITEM_ICON_SIZE;
};
class InventoryBuilder {
std::shared_ptr<InventoryView> 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<InventoryView> build();
};
#endif // FRONTEND_INVENTORY_VIEW_H_ #endif // FRONTEND_INVENTORY_VIEW_H_
+19 -47
View File
@@ -179,7 +179,7 @@ std::shared_ptr<InventoryView> HudRenderer::createContentAccess() {
accessInventory->getSlot(id-1).set(ItemStack(id, 1)); accessInventory->getSlot(id-1).set(ItemStack(id, 1));
} }
SlotLayout slotLayout(glm::vec2(), false, true, SlotLayout slotLayout(-1, glm::vec2(), false, true,
[=](ItemStack& item) { [=](ItemStack& item) {
auto copy = ItemStack(item); auto copy = ItemStack(item);
inventory->move(copy, indices); inventory->move(copy, indices);
@@ -188,41 +188,25 @@ std::shared_ptr<InventoryView> HudRenderer::createContentAccess() {
inventory->getSlot(player->getChosenSlot()).set(item); inventory->getSlot(player->getChosenSlot()).set(item);
}); });
InventoryBuilder builder; InventoryBuilder builder(frontend, *interaction);
builder.addGrid(8, itemsCount-1, glm::vec2(), 8, true, slotLayout); builder.addGrid(8, itemsCount-1, glm::vec2(), 8, true, slotLayout);
auto layout = builder.build(); auto view = builder.build();
view->bind(accessInventory);
auto contentAccess = std::make_shared<InventoryView>( return view;
content,
frontend,
interaction.get(),
accessInventory,
std::move(layout)
);
contentAccess->build();
return contentAccess;
} }
std::shared_ptr<InventoryView> HudRenderer::createHotbar() { std::shared_ptr<InventoryView> HudRenderer::createHotbar() {
auto level = frontend->getLevel(); auto level = frontend->getLevel();
auto player = level->player; auto player = level->player;
auto inventory = player->getInventory(); auto inventory = player->getInventory();
auto content = level->content;
SlotLayout slotLayout(glm::vec2(), false, false, nullptr, nullptr); SlotLayout slotLayout(-1, glm::vec2(), false, false, nullptr, nullptr);
InventoryBuilder builder; InventoryBuilder builder(frontend, *interaction);
builder.addGrid(10, 10, glm::vec2(), 4, true, slotLayout); 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)); view->setOrigin(glm::vec2(view->getSize().x/2, 0));
auto view = std::make_shared<InventoryView>( view->bind(inventory);
content,
frontend,
interaction.get(),
inventory,
std::move(layout)
);
view->build();
view->setInteractive(false); view->setInteractive(false);
return view; return view;
} }
@@ -231,24 +215,15 @@ std::shared_ptr<InventoryView> HudRenderer::createInventory() {
auto level = frontend->getLevel(); auto level = frontend->getLevel();
auto player = level->player; auto player = level->player;
auto inventory = player->getInventory(); 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(); stack.clear();
}, nullptr); }, nullptr);
InventoryBuilder builder; InventoryBuilder builder(frontend, *interaction);
builder.addGrid(10, inventory->size(), glm::vec2(), 4, true, slotLayout); builder.addGrid(10, inventory->size(), glm::vec2(), 4, true, slotLayout);
auto layout = builder.build(); auto view = builder.build();
view->bind(inventory);
auto view = std::make_shared<InventoryView>(
content,
frontend,
interaction.get(),
inventory,
std::move(layout)
);
view->build();
return view; return view;
} }
@@ -261,12 +236,11 @@ HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend)
interaction = std::make_unique<InventoryInteraction>(); interaction = std::make_unique<InventoryInteraction>();
grabbedItemView = std::make_shared<SlotView>( grabbedItemView = std::make_shared<SlotView>(
interaction->getGrabbedItem(),
frontend, frontend,
interaction.get(), *interaction,
frontend->getLevel()->content, SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr)
SlotLayout(glm::vec2(), false, false, nullptr, nullptr)
); );
grabbedItemView->bind(interaction->getGrabbedItem());
grabbedItemView->setColor(glm::vec4()); grabbedItemView->setColor(glm::vec4());
grabbedItemView->setInteractive(false); grabbedItemView->setInteractive(false);
@@ -417,10 +391,8 @@ void HudRenderer::draw(const GfxContext& ctx){
} }
if (inventoryOpen) { if (inventoryOpen) {
auto caLayout = contentAccess->getLayout(); float caWidth = contentAccess->getSize().x;
auto invLayout = inventoryView->getLayout(); glm::vec2 invSize = inventoryView->getSize();
float caWidth = caLayout->getSize().x;
glm::vec2 invSize = invLayout->getSize();
float width = viewport.getWidth(); float width = viewport.getWidth();