InventoryView inventory property
This commit is contained in:
@@ -0,0 +1,364 @@
|
||||
#include "InventoryView.hpp"
|
||||
#include "../../../assets/Assets.h"
|
||||
#include "../../../content/Content.h"
|
||||
#include "../../../frontend/LevelFrontend.h"
|
||||
#include "../../../items/Inventories.h"
|
||||
#include "../../../items/Inventory.h"
|
||||
#include "../../../items/ItemDef.h"
|
||||
#include "../../../items/ItemStack.h"
|
||||
#include "../../../logic/scripting/scripting.h"
|
||||
#include "../../../maths/voxmaths.h"
|
||||
#include "../../../objects/Player.h"
|
||||
#include "../../../util/stringutil.h"
|
||||
#include "../../../voxels/Block.h"
|
||||
#include "../../../window/Events.h"
|
||||
#include "../../../window/input.h"
|
||||
#include "../../../world/Level.h"
|
||||
#include "../../core/Atlas.hpp"
|
||||
#include "../../core/Batch2D.hpp"
|
||||
#include "../../core/Font.hpp"
|
||||
#include "../../core/GfxContext.hpp"
|
||||
#include "../../core/Shader.hpp"
|
||||
#include "../../render/BlocksPreview.hpp"
|
||||
#include "../GUI.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
using namespace gui;
|
||||
|
||||
SlotLayout::SlotLayout(
|
||||
int index,
|
||||
glm::vec2 position,
|
||||
bool background,
|
||||
bool itemSource,
|
||||
slotcallback updateFunc,
|
||||
slotcallback shareFunc,
|
||||
slotcallback rightClick
|
||||
) : index(index),
|
||||
position(position),
|
||||
background(background),
|
||||
itemSource(itemSource),
|
||||
updateFunc(updateFunc),
|
||||
shareFunc(shareFunc),
|
||||
rightClick(rightClick) {}
|
||||
|
||||
InventoryBuilder::InventoryBuilder() {
|
||||
view = std::make_shared<InventoryView>();
|
||||
}
|
||||
|
||||
void InventoryBuilder::addGrid(
|
||||
int cols, int count,
|
||||
glm::vec2 pos,
|
||||
int padding,
|
||||
bool addpanel,
|
||||
SlotLayout slotLayout
|
||||
) {
|
||||
const int slotSize = InventoryView::SLOT_SIZE;
|
||||
const int interval = InventoryView::SLOT_INTERVAL;
|
||||
|
||||
int rows = ceildiv(count, cols);
|
||||
|
||||
uint width = cols * (slotSize + interval) - interval + padding*2;
|
||||
uint height = rows * (slotSize + interval) - interval + padding*2;
|
||||
|
||||
glm::vec2 vsize = view->getSize();
|
||||
if (pos.x + width > vsize.x) {
|
||||
vsize.x = pos.x + width;
|
||||
}
|
||||
if (pos.y + height > vsize.y) {
|
||||
vsize.y = pos.y + height;
|
||||
}
|
||||
view->setSize(vsize);
|
||||
|
||||
if (addpanel) {
|
||||
auto panel = std::make_shared<gui::Container>(glm::vec2(width, height));
|
||||
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f));
|
||||
view->add(panel, pos);
|
||||
}
|
||||
|
||||
for (int row = 0; row < rows; row++) {
|
||||
for (int col = 0; col < cols; col++) {
|
||||
if (row * cols + col >= count) {
|
||||
break;
|
||||
}
|
||||
glm::vec2 position (
|
||||
col * (slotSize + interval) + padding,
|
||||
row * (slotSize + interval) + padding
|
||||
);
|
||||
auto builtSlot = slotLayout;
|
||||
builtSlot.index = row * cols + col;
|
||||
builtSlot.position = position;
|
||||
add(builtSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryBuilder::add(SlotLayout layout) {
|
||||
view->add(view->addSlot(layout), layout.position);
|
||||
}
|
||||
|
||||
std::shared_ptr<InventoryView> InventoryBuilder::build() {
|
||||
return view;
|
||||
}
|
||||
|
||||
SlotView::SlotView(
|
||||
SlotLayout layout
|
||||
) : UINode(glm::vec2(InventoryView::SLOT_SIZE)),
|
||||
layout(layout)
|
||||
{
|
||||
setColor(glm::vec4(0, 0, 0, 0.2f));
|
||||
}
|
||||
|
||||
void SlotView::draw(const GfxContext* pctx, Assets* assets) {
|
||||
if (bound == nullptr)
|
||||
return;
|
||||
|
||||
const int slotSize = InventoryView::SLOT_SIZE;
|
||||
|
||||
ItemStack& stack = *bound;
|
||||
glm::vec4 tint(1.0f);
|
||||
glm::vec2 pos = calcPos();
|
||||
glm::vec4 color = getColor();
|
||||
|
||||
if (hover || highlighted) {
|
||||
tint *= 1.333f;
|
||||
color = glm::vec4(1, 1, 1, 0.2f);
|
||||
}
|
||||
|
||||
auto batch = pctx->getBatch2D();
|
||||
batch->setColor(color);
|
||||
if (color.a > 0.0) {
|
||||
batch->texture(nullptr);
|
||||
if (highlighted) {
|
||||
batch->rect(pos.x-4, pos.y-4, slotSize+8, slotSize+8);
|
||||
} else {
|
||||
batch->rect(pos.x, pos.y, slotSize, slotSize);
|
||||
}
|
||||
}
|
||||
|
||||
batch->setColor(glm::vec4(1.0f));
|
||||
|
||||
auto previews = assets->getAtlas("block-previews");
|
||||
auto indices = content->getIndices();
|
||||
|
||||
ItemDef* item = indices->getItemDef(stack.getItemId());
|
||||
switch (item->iconType) {
|
||||
case item_icon_type::none:
|
||||
break;
|
||||
case item_icon_type::block: {
|
||||
const Block& cblock = content->requireBlock(item->icon);
|
||||
batch->texture(previews->getTexture());
|
||||
|
||||
UVRegion region = previews->get(cblock.name);
|
||||
batch->rect(
|
||||
pos.x, pos.y, slotSize, slotSize,
|
||||
0, 0, 0, region, false, true, tint);
|
||||
break;
|
||||
}
|
||||
case item_icon_type::sprite: {
|
||||
size_t index = item->icon.find(':');
|
||||
std::string name = item->icon.substr(index+1);
|
||||
UVRegion region(0.0f, 0.0, 1.0f, 1.0f);
|
||||
if (index == std::string::npos) {
|
||||
batch->texture(assets->getTexture(name));
|
||||
} else {
|
||||
std::string atlasname = item->icon.substr(0, index);
|
||||
Atlas* atlas = assets->getAtlas(atlasname);
|
||||
if (atlas && atlas->has(name)) {
|
||||
region = atlas->get(name);
|
||||
batch->texture(atlas->getTexture());
|
||||
}
|
||||
}
|
||||
batch->rect(
|
||||
pos.x, pos.y, slotSize, slotSize,
|
||||
0, 0, 0, region, false, true, tint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getCount() > 1) {
|
||||
auto font = assets->getFont("normal");
|
||||
std::wstring text = std::to_wstring(stack.getCount());
|
||||
|
||||
int x = pos.x+slotSize-text.length()*8;
|
||||
int y = pos.y+slotSize-16;
|
||||
|
||||
batch->setColor({0, 0, 0, 1.0f});
|
||||
font->draw(batch, text, x+1, y+1);
|
||||
batch->setColor(glm::vec4(1.0f));
|
||||
font->draw(batch, text, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void SlotView::setHighlighted(bool flag) {
|
||||
highlighted = flag;
|
||||
}
|
||||
|
||||
bool SlotView::isHighlighted() const {
|
||||
return highlighted;
|
||||
}
|
||||
|
||||
void SlotView::clicked(gui::GUI* gui, mousecode button) {
|
||||
if (bound == nullptr)
|
||||
return;
|
||||
|
||||
auto exchangeSlot = std::dynamic_pointer_cast<SlotView>(gui->get(EXCHANGE_SLOT_NAME));
|
||||
if (exchangeSlot == nullptr) {
|
||||
return;
|
||||
}
|
||||
ItemStack& grabbed = exchangeSlot->getStack();
|
||||
ItemStack& stack = *bound;
|
||||
|
||||
if (button == mousecode::BUTTON_1) {
|
||||
if (Events::pressed(keycode::LEFT_SHIFT)) {
|
||||
if (layout.shareFunc) {
|
||||
layout.shareFunc(layout.index, stack);
|
||||
}
|
||||
if (layout.updateFunc) {
|
||||
layout.updateFunc(layout.index, stack);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!layout.itemSource && stack.accepts(grabbed)) {
|
||||
stack.move(grabbed, content->getIndices());
|
||||
} else {
|
||||
if (layout.itemSource) {
|
||||
if (grabbed.isEmpty()) {
|
||||
grabbed.set(stack);
|
||||
} else {
|
||||
grabbed.clear();
|
||||
}
|
||||
} else {
|
||||
std::swap(grabbed, stack);
|
||||
}
|
||||
}
|
||||
} else if (button == mousecode::BUTTON_2) {
|
||||
if (layout.rightClick) {
|
||||
layout.rightClick(inventoryid, stack);
|
||||
if (layout.updateFunc) {
|
||||
layout.updateFunc(layout.index, stack);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (layout.itemSource)
|
||||
return;
|
||||
if (grabbed.isEmpty()) {
|
||||
if (!stack.isEmpty()) {
|
||||
grabbed.set(stack);
|
||||
int halfremain = stack.getCount() / 2;
|
||||
grabbed.setCount(stack.getCount() - halfremain);
|
||||
stack.setCount(halfremain);
|
||||
}
|
||||
} else {
|
||||
if (stack.isEmpty()) {
|
||||
stack.set(grabbed);
|
||||
stack.setCount(1);
|
||||
grabbed.setCount(grabbed.getCount()-1);
|
||||
} else if (stack.accepts(grabbed)){
|
||||
stack.setCount(stack.getCount()+1);
|
||||
grabbed.setCount(grabbed.getCount()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layout.updateFunc) {
|
||||
layout.updateFunc(layout.index, stack);
|
||||
}
|
||||
}
|
||||
|
||||
void SlotView::onFocus(gui::GUI* gui) {
|
||||
clicked(gui, mousecode::BUTTON_1);
|
||||
}
|
||||
|
||||
void SlotView::bind(
|
||||
int64_t inventoryid,
|
||||
ItemStack& stack,
|
||||
const Content* content
|
||||
) {
|
||||
this->inventoryid = inventoryid;
|
||||
bound = &stack;
|
||||
this->content = content;
|
||||
}
|
||||
|
||||
const SlotLayout& SlotView::getLayout() const {
|
||||
return layout;
|
||||
}
|
||||
|
||||
ItemStack& SlotView::getStack() {
|
||||
return *bound;
|
||||
}
|
||||
|
||||
InventoryView::InventoryView() : Container(glm::vec2()) {
|
||||
setColor(glm::vec4(0, 0, 0, 0.0f));
|
||||
}
|
||||
|
||||
InventoryView::~InventoryView() {}
|
||||
|
||||
|
||||
std::shared_ptr<SlotView> InventoryView::addSlot(SlotLayout layout) {
|
||||
uint width = InventoryView::SLOT_SIZE + layout.padding;
|
||||
uint height = InventoryView::SLOT_SIZE + layout.padding;
|
||||
|
||||
auto pos = layout.position;
|
||||
auto vsize = getSize();
|
||||
if (pos.x + width > vsize.x) {
|
||||
vsize.x = pos.x + width;
|
||||
}
|
||||
if (pos.y + height > vsize.y) {
|
||||
vsize.y = pos.y + height;
|
||||
}
|
||||
setSize(vsize);
|
||||
|
||||
auto slot = std::make_shared<SlotView>(layout);
|
||||
if (!layout.background) {
|
||||
slot->setColor(glm::vec4());
|
||||
}
|
||||
slots.push_back(slot.get());
|
||||
return slot;
|
||||
}
|
||||
|
||||
std::shared_ptr<Inventory> InventoryView::getInventory() const {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
|
||||
size_t InventoryView::getSlotsCount() const {
|
||||
return slots.size();
|
||||
}
|
||||
|
||||
void InventoryView::bind(
|
||||
std::shared_ptr<Inventory> inventory,
|
||||
const Content* content
|
||||
) {
|
||||
this->inventory = inventory;
|
||||
this->content = content;
|
||||
for (auto slot : slots) {
|
||||
slot->bind(
|
||||
inventory->getId(),
|
||||
inventory->getSlot(slot->getLayout().index),
|
||||
content
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryView::unbind() {
|
||||
inventory = nullptr;
|
||||
}
|
||||
|
||||
void InventoryView::setSelected(int index) {
|
||||
for (size_t i = 0; i < slots.size(); i++) {
|
||||
slots[i]->setHighlighted(static_cast<int>(i) == index);
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryView::setPos(glm::vec2 pos) {
|
||||
Container::setPos(pos - origin);
|
||||
}
|
||||
|
||||
void InventoryView::setOrigin(glm::vec2 origin) {
|
||||
this->origin = origin;
|
||||
}
|
||||
|
||||
glm::vec2 InventoryView::getOrigin() const {
|
||||
return origin;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
#ifndef FRONTEND_INVENTORY_VIEW_H_
|
||||
#define FRONTEND_INVENTORY_VIEW_H_
|
||||
|
||||
#include "UINode.hpp"
|
||||
#include "Container.hpp"
|
||||
#include "../../../typedefs.h"
|
||||
#include "../../../constants.h"
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class Assets;
|
||||
class GfxContext;
|
||||
class Content;
|
||||
class ItemStack;
|
||||
class ContentIndices;
|
||||
class LevelFrontend;
|
||||
class Inventory;
|
||||
|
||||
namespace gui {
|
||||
class UiXmlReader;
|
||||
}
|
||||
|
||||
namespace gui {
|
||||
using slotcallback = std::function<void(uint, ItemStack&)>;
|
||||
|
||||
struct SlotLayout {
|
||||
int index;
|
||||
glm::vec2 position;
|
||||
bool background;
|
||||
bool itemSource;
|
||||
slotcallback updateFunc;
|
||||
slotcallback shareFunc;
|
||||
slotcallback rightClick;
|
||||
int padding = 0;
|
||||
|
||||
SlotLayout(
|
||||
int index,
|
||||
glm::vec2 position,
|
||||
bool background,
|
||||
bool itemSource,
|
||||
slotcallback updateFunc,
|
||||
slotcallback shareFunc,
|
||||
slotcallback rightClick
|
||||
);
|
||||
};
|
||||
|
||||
class SlotView : public gui::UINode {
|
||||
const Content* content;
|
||||
SlotLayout layout;
|
||||
bool highlighted = false;
|
||||
|
||||
int64_t inventoryid = 0;
|
||||
ItemStack* bound = nullptr;
|
||||
public:
|
||||
SlotView(SlotLayout layout);
|
||||
|
||||
virtual void draw(const GfxContext* pctx, Assets* assets) override;
|
||||
|
||||
void setHighlighted(bool flag);
|
||||
bool isHighlighted() const;
|
||||
|
||||
virtual void clicked(gui::GUI*, mousecode) override;
|
||||
virtual void onFocus(gui::GUI*) override;
|
||||
|
||||
void bind(
|
||||
int64_t inventoryid,
|
||||
ItemStack& stack,
|
||||
const Content* content
|
||||
);
|
||||
|
||||
ItemStack& getStack();
|
||||
const SlotLayout& getLayout() const;
|
||||
|
||||
static inline std::string EXCHANGE_SLOT_NAME = "exchange-slot";
|
||||
};
|
||||
|
||||
class InventoryView : public gui::Container {
|
||||
const Content* content;
|
||||
|
||||
std::shared_ptr<Inventory> inventory;
|
||||
|
||||
std::vector<SlotView*> slots;
|
||||
glm::vec2 origin {};
|
||||
public:
|
||||
InventoryView();
|
||||
virtual ~InventoryView();
|
||||
|
||||
virtual void setPos(glm::vec2 pos) override;
|
||||
|
||||
void setOrigin(glm::vec2 origin);
|
||||
glm::vec2 getOrigin() const;
|
||||
|
||||
void setSelected(int index);
|
||||
|
||||
void bind(
|
||||
std::shared_ptr<Inventory> inventory,
|
||||
const Content* content
|
||||
);
|
||||
|
||||
void unbind();
|
||||
|
||||
std::shared_ptr<SlotView> addSlot(SlotLayout layout);
|
||||
|
||||
std::shared_ptr<Inventory> getInventory() const;
|
||||
|
||||
size_t getSlotsCount() const;
|
||||
|
||||
static const int SLOT_INTERVAL = 4;
|
||||
static const int SLOT_SIZE = ITEM_ICON_SIZE;
|
||||
};
|
||||
|
||||
class InventoryBuilder {
|
||||
std::shared_ptr<InventoryView> view;
|
||||
public:
|
||||
InventoryBuilder();
|
||||
|
||||
/// @brief Add slots grid to inventory view
|
||||
/// @param cols grid columns
|
||||
/// @param count total number of grid slots
|
||||
/// @param pos position of the first slot of the grid
|
||||
/// @param padding additional space around the grid
|
||||
/// @param addpanel automatically create panel behind the grid
|
||||
/// with size including padding
|
||||
/// @param slotLayout slot settings (index and position are ignored)
|
||||
void addGrid(
|
||||
int cols, int count,
|
||||
glm::vec2 pos,
|
||||
int padding,
|
||||
bool addpanel,
|
||||
SlotLayout slotLayout
|
||||
);
|
||||
|
||||
void add(SlotLayout slotLayout);
|
||||
std::shared_ptr<InventoryView> build();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // FRONTEND_INVENTORY_VIEW_H_
|
||||
+129
-31
@@ -1,8 +1,5 @@
|
||||
#include "gui_xml.hpp"
|
||||
|
||||
#include <charconv>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "elements/Panel.hpp"
|
||||
#include "elements/Image.hpp"
|
||||
#include "elements/Button.hpp"
|
||||
@@ -10,12 +7,17 @@
|
||||
#include "elements/TextBox.hpp"
|
||||
#include "elements/TrackBar.hpp"
|
||||
#include "elements/InputBindBox.hpp"
|
||||
#include "elements/InventoryView.hpp"
|
||||
|
||||
#include "../../frontend/locale/langs.h"
|
||||
#include "../../items/Inventory.h"
|
||||
#include "../../logic/scripting/scripting.h"
|
||||
#include "../../maths/voxmaths.h"
|
||||
#include "../../util/stringutil.h"
|
||||
#include "../../window/Events.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace gui;
|
||||
|
||||
static Align align_from_string(const std::string& str, Align def) {
|
||||
@@ -84,12 +86,11 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no
|
||||
node.setVisible(element->attr("visible").asBool());
|
||||
}
|
||||
if (element->has("position-func")) {
|
||||
auto supplier = scripting::create_vec2_supplier(
|
||||
node.setPositionFunc(scripting::create_vec2_supplier(
|
||||
reader.getEnvironment(),
|
||||
element->attr("position-func").getText(),
|
||||
reader.getFilename()+".lua"
|
||||
);
|
||||
node.setPositionFunc(supplier);
|
||||
));
|
||||
}
|
||||
if (element->has("hover-color")) {
|
||||
node.setHoverColor(element->attr("hover-color").asColor());
|
||||
@@ -208,12 +209,11 @@ static std::shared_ptr<UINode> readLabel(UiXmlReader& reader, xml::xmlelement el
|
||||
);
|
||||
}
|
||||
if (element->has("supplier")) {
|
||||
auto supplier = scripting::create_wstring_supplier(
|
||||
label->textSupplier(scripting::create_wstring_supplier(
|
||||
reader.getEnvironment(),
|
||||
element->attr("supplier").getText(),
|
||||
reader.getFilename()
|
||||
);
|
||||
label->textSupplier(supplier);
|
||||
));
|
||||
}
|
||||
if (element->has("multiline")) {
|
||||
label->setMultiline(element->attr("multiline").asBool());
|
||||
@@ -268,21 +268,19 @@ static std::shared_ptr<UINode> readCheckBox(UiXmlReader& reader, xml::xmlelement
|
||||
_readPanel(reader, element, *checkbox);
|
||||
|
||||
if (element->has("consumer")) {
|
||||
auto consumer = scripting::create_bool_consumer(
|
||||
checkbox->setConsumer(scripting::create_bool_consumer(
|
||||
reader.getEnvironment(),
|
||||
element->attr("consumer").getText(),
|
||||
reader.getFilename()
|
||||
);
|
||||
checkbox->setConsumer(consumer);
|
||||
));
|
||||
}
|
||||
|
||||
if (element->has("supplier")) {
|
||||
auto supplier = scripting::create_bool_supplier(
|
||||
checkbox->setSupplier(scripting::create_bool_supplier(
|
||||
reader.getEnvironment(),
|
||||
element->attr("supplier").getText(),
|
||||
reader.getFilename()
|
||||
);
|
||||
checkbox->setSupplier(supplier);
|
||||
));
|
||||
}
|
||||
return checkbox;
|
||||
}
|
||||
@@ -306,21 +304,19 @@ static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, xml::xmlelement
|
||||
}
|
||||
|
||||
if (element->has("consumer")) {
|
||||
auto consumer = scripting::create_wstring_consumer(
|
||||
textbox->setTextConsumer(scripting::create_wstring_consumer(
|
||||
reader.getEnvironment(),
|
||||
element->attr("consumer").getText(),
|
||||
reader.getFilename()
|
||||
);
|
||||
textbox->setTextConsumer(consumer);
|
||||
));
|
||||
}
|
||||
|
||||
if (element->has("supplier")) {
|
||||
auto supplier = scripting::create_wstring_supplier(
|
||||
textbox->setTextSupplier(scripting::create_wstring_supplier(
|
||||
reader.getEnvironment(),
|
||||
element->attr("supplier").getText(),
|
||||
reader.getFilename()
|
||||
);
|
||||
textbox->setTextSupplier(supplier);
|
||||
));
|
||||
}
|
||||
if (element->has("focused-color")) {
|
||||
textbox->setFocusedColor(element->attr("focused-color").asColor());
|
||||
@@ -329,12 +325,11 @@ static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, xml::xmlelement
|
||||
textbox->setErrorColor(element->attr("error-color").asColor());
|
||||
}
|
||||
if (element->has("validator")) {
|
||||
auto validator = scripting::create_wstring_validator(
|
||||
textbox->setTextValidator(scripting::create_wstring_validator(
|
||||
reader.getEnvironment(),
|
||||
element->attr("validator").getText(),
|
||||
reader.getFilename()
|
||||
);
|
||||
textbox->setTextValidator(validator);
|
||||
));
|
||||
}
|
||||
return textbox;
|
||||
}
|
||||
@@ -351,24 +346,22 @@ static std::shared_ptr<UINode> readTrackBar(UiXmlReader& reader, xml::xmlelement
|
||||
float max = element->attr("max", "1.0").asFloat();
|
||||
float def = element->attr("value", "0.0").asFloat();
|
||||
float step = element->attr("step", "1.0").asFloat();
|
||||
int trackWidth = element->attr("track-width", "12.0").asInt();
|
||||
int trackWidth = element->attr("track-width", "12").asInt();
|
||||
auto bar = std::make_shared<TrackBar>(min, max, def, step, trackWidth);
|
||||
_readUINode(reader, element, *bar);
|
||||
if (element->has("consumer")) {
|
||||
auto consumer = scripting::create_number_consumer(
|
||||
bar->setConsumer(scripting::create_number_consumer(
|
||||
reader.getEnvironment(),
|
||||
element->attr("consumer").getText(),
|
||||
reader.getFilename()
|
||||
);
|
||||
bar->setConsumer(consumer);
|
||||
));
|
||||
}
|
||||
if (element->has("supplier")) {
|
||||
auto supplier = scripting::create_number_supplier(
|
||||
bar->setSupplier(scripting::create_number_supplier(
|
||||
reader.getEnvironment(),
|
||||
element->attr("supplier").getText(),
|
||||
reader.getFilename()
|
||||
);
|
||||
bar->setSupplier(supplier);
|
||||
));
|
||||
}
|
||||
if (element->has("track-color")) {
|
||||
bar->setTrackColor(element->attr("track-color").asColor());
|
||||
@@ -389,6 +382,110 @@ static std::shared_ptr<UINode> readInputBindBox(UiXmlReader& reader, xml::xmlele
|
||||
return bindbox;
|
||||
}
|
||||
|
||||
static slotcallback readSlotFunc(InventoryView* view, UiXmlReader& reader, xml::xmlelement& element, const std::string& attr) {
|
||||
auto consumer = scripting::create_int_array_consumer(
|
||||
reader.getEnvironment(),
|
||||
element->attr(attr).getText()
|
||||
);
|
||||
return [=](uint slot, ItemStack& stack) {
|
||||
int args[] {int(view->getInventory()->getId()), int(slot)};
|
||||
consumer(args, 2);
|
||||
};
|
||||
}
|
||||
|
||||
static void readSlot(InventoryView* view, UiXmlReader& reader, xml::xmlelement element) {
|
||||
int index = element->attr("index", "0").asInt();
|
||||
bool itemSource = element->attr("item-source", "false").asBool();
|
||||
SlotLayout layout(index, glm::vec2(), true, itemSource, nullptr, nullptr, nullptr);
|
||||
if (element->has("pos")) {
|
||||
layout.position = element->attr("pos").asVec2();
|
||||
}
|
||||
if (element->has("updatefunc")) {
|
||||
layout.updateFunc = readSlotFunc(view, reader, element, "updatefunc");
|
||||
}
|
||||
if (element->has("sharefunc")) {
|
||||
layout.shareFunc = readSlotFunc(view, reader, element, "sharefunc");
|
||||
}
|
||||
if (element->has("onrightclick")) {
|
||||
layout.rightClick = readSlotFunc(view, reader, element, "onrightclick");
|
||||
}
|
||||
auto slot = view->addSlot(layout);
|
||||
reader.readUINode(reader, element, *slot);
|
||||
view->add(slot);
|
||||
}
|
||||
|
||||
static void readSlotsGrid(InventoryView* view, UiXmlReader& reader, xml::xmlelement element) {
|
||||
int startIndex = element->attr("start-index", "0").asInt();
|
||||
int rows = element->attr("rows", "0").asInt();
|
||||
int cols = element->attr("cols", "0").asInt();
|
||||
int count = element->attr("count", "0").asInt();
|
||||
const int slotSize = InventoryView::SLOT_SIZE;
|
||||
int interval = element->attr("interval", "-1").asInt();
|
||||
if (interval < 0) {
|
||||
interval = InventoryView::SLOT_INTERVAL;
|
||||
}
|
||||
int padding = element->attr("padding", "-1").asInt();
|
||||
if (padding < 0) {
|
||||
padding = interval;
|
||||
}
|
||||
if (rows == 0) {
|
||||
rows = ceildiv(count, cols);
|
||||
} else if (cols == 0) {
|
||||
cols = ceildiv(count, rows);
|
||||
} else if (count == 0) {
|
||||
count = rows * cols;
|
||||
}
|
||||
bool itemSource = element->attr("item-source", "false").asBool();
|
||||
SlotLayout layout(-1, glm::vec2(), true, itemSource, nullptr, nullptr, nullptr);
|
||||
if (element->has("pos")) {
|
||||
layout.position = element->attr("pos").asVec2();
|
||||
}
|
||||
if (element->has("updatefunc")) {
|
||||
layout.updateFunc = readSlotFunc(view, reader, element, "updatefunc");
|
||||
}
|
||||
if (element->has("sharefunc")) {
|
||||
layout.shareFunc = readSlotFunc(view, reader, element, "sharefunc");
|
||||
}
|
||||
if (element->has("onrightclick")) {
|
||||
layout.rightClick = readSlotFunc(view, reader, element, "onrightclick");
|
||||
}
|
||||
layout.padding = padding;
|
||||
|
||||
int idx = 0;
|
||||
for (int row = 0; row < rows; row++) {
|
||||
for (int col = 0; col < cols; col++, idx++) {
|
||||
if (idx >= count) {
|
||||
return;
|
||||
}
|
||||
SlotLayout slotLayout = layout;
|
||||
slotLayout.index = startIndex + idx;
|
||||
slotLayout.position += glm::vec2(
|
||||
padding + col * (slotSize + interval),
|
||||
padding + (rows-row-1) * (slotSize + interval)
|
||||
);
|
||||
auto slot = view->addSlot(slotLayout);
|
||||
view->add(slot, slotLayout.position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::shared_ptr<UINode> readInventory(UiXmlReader& reader, xml::xmlelement element) {
|
||||
auto view = std::make_shared<InventoryView>();
|
||||
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f)); // todo: fixme
|
||||
reader.addIgnore("slot");
|
||||
reader.addIgnore("slots-grid");
|
||||
reader.readUINode(reader, element, *view);
|
||||
|
||||
for (auto& sub : element->getElements()) {
|
||||
if (sub->getTag() == "slot") {
|
||||
readSlot(view.get(), reader, sub);
|
||||
} else if (sub->getTag() == "slots-grid") {
|
||||
readSlotsGrid(view.get(), reader, sub);
|
||||
}
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
UiXmlReader::UiXmlReader(const scriptenv& env) : env(env) {
|
||||
contextStack.push("");
|
||||
add("image", readImage);
|
||||
@@ -400,6 +497,7 @@ UiXmlReader::UiXmlReader(const scriptenv& env) : env(env) {
|
||||
add("trackbar", readTrackBar);
|
||||
add("container", readContainer);
|
||||
add("bindbox", readInputBindBox);
|
||||
add("inventory", readInventory);
|
||||
}
|
||||
|
||||
void UiXmlReader::add(const std::string& tag, uinode_reader reader) {
|
||||
|
||||
Reference in New Issue
Block a user