Merge branch 'main' into lua_audio
This commit is contained in:
commit
dc13c109e6
@ -16,6 +16,7 @@
|
|||||||
#include "../content/Content.h"
|
#include "../content/Content.h"
|
||||||
#include "../items/ItemDef.h"
|
#include "../items/ItemDef.h"
|
||||||
#include "../items/Inventory.h"
|
#include "../items/Inventory.h"
|
||||||
|
#include "../items/Inventories.h"
|
||||||
#include "../maths/voxmaths.h"
|
#include "../maths/voxmaths.h"
|
||||||
#include "../objects/Player.h"
|
#include "../objects/Player.h"
|
||||||
#include "../voxels/Block.h"
|
#include "../voxels/Block.h"
|
||||||
@ -47,7 +48,7 @@ InventoryBuilder::InventoryBuilder() {
|
|||||||
/** Add slots grid to inventory view
|
/** Add slots grid to inventory view
|
||||||
* @param cols grid columns
|
* @param cols grid columns
|
||||||
* @param count total number of grid slots
|
* @param count total number of grid slots
|
||||||
* @param coord position of the first slot of the grid
|
* @param pos position of the first slot of the grid
|
||||||
* @param padding additional space around the grid
|
* @param padding additional space around the grid
|
||||||
* @param addpanel automatically create panel behind the grid
|
* @param addpanel automatically create panel behind the grid
|
||||||
* with size including padding
|
* with size including padding
|
||||||
@ -55,7 +56,7 @@ InventoryBuilder::InventoryBuilder() {
|
|||||||
*/
|
*/
|
||||||
void InventoryBuilder::addGrid(
|
void InventoryBuilder::addGrid(
|
||||||
int cols, int count,
|
int cols, int count,
|
||||||
glm::vec2 coord,
|
glm::vec2 pos,
|
||||||
int padding,
|
int padding,
|
||||||
bool addpanel,
|
bool addpanel,
|
||||||
SlotLayout slotLayout)
|
SlotLayout slotLayout)
|
||||||
@ -69,18 +70,18 @@ void InventoryBuilder::addGrid(
|
|||||||
uint height = rows * (slotSize + interval) - interval + padding*2;
|
uint height = rows * (slotSize + interval) - interval + padding*2;
|
||||||
|
|
||||||
glm::vec2 vsize = view->getSize();
|
glm::vec2 vsize = view->getSize();
|
||||||
if (coord.x + width > vsize.x) {
|
if (pos.x + width > vsize.x) {
|
||||||
vsize.x = coord.x + width;
|
vsize.x = pos.x + width;
|
||||||
}
|
}
|
||||||
if (coord.y + height > vsize.y) {
|
if (pos.y + height > vsize.y) {
|
||||||
vsize.y = coord.y + height;
|
vsize.y = pos.y + height;
|
||||||
}
|
}
|
||||||
view->setSize(vsize);
|
view->setSize(vsize);
|
||||||
|
|
||||||
if (addpanel) {
|
if (addpanel) {
|
||||||
auto panel = std::make_shared<gui::Container>(coord, glm::vec2(width, height));
|
auto panel = std::make_shared<gui::Container>(glm::vec2(width, height));
|
||||||
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f));
|
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f));
|
||||||
view->add(panel);
|
view->add(panel, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int row = 0; row < rows; row++) {
|
for (int row = 0; row < rows; row++) {
|
||||||
@ -109,7 +110,7 @@ std::shared_ptr<InventoryView> InventoryBuilder::build() {
|
|||||||
|
|
||||||
SlotView::SlotView(
|
SlotView::SlotView(
|
||||||
SlotLayout layout
|
SlotLayout layout
|
||||||
) : UINode(glm::vec2(), glm::vec2(InventoryView::SLOT_SIZE)),
|
) : UINode(glm::vec2(InventoryView::SLOT_SIZE)),
|
||||||
layout(layout)
|
layout(layout)
|
||||||
{
|
{
|
||||||
setColor(glm::vec4(0, 0, 0, 0.2f));
|
setColor(glm::vec4(0, 0, 0, 0.2f));
|
||||||
@ -121,7 +122,7 @@ void SlotView::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
|
|
||||||
ItemStack& stack = *bound;
|
ItemStack& stack = *bound;
|
||||||
|
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
|
|
||||||
int slotSize = InventoryView::SLOT_SIZE;
|
int slotSize = InventoryView::SLOT_SIZE;
|
||||||
|
|
||||||
@ -137,9 +138,9 @@ void SlotView::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
if (color.a > 0.0) {
|
if (color.a > 0.0) {
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
if (highlighted) {
|
if (highlighted) {
|
||||||
batch->rect(coord.x-4, coord.y-4, slotSize+8, slotSize+8);
|
batch->rect(pos.x-4, pos.y-4, slotSize+8, slotSize+8);
|
||||||
} else {
|
} else {
|
||||||
batch->rect(coord.x, coord.y, slotSize, slotSize);
|
batch->rect(pos.x, pos.y, slotSize, slotSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +159,7 @@ void SlotView::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
|
|
||||||
UVRegion region = previews->get(cblock.name);
|
UVRegion region = previews->get(cblock.name);
|
||||||
batch->rect(
|
batch->rect(
|
||||||
coord.x, coord.y, slotSize, slotSize,
|
pos.x, pos.y, slotSize, slotSize,
|
||||||
0, 0, 0, region, false, true, tint);
|
0, 0, 0, region, false, true, tint);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -177,7 +178,7 @@ void SlotView::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
batch->rect(
|
batch->rect(
|
||||||
coord.x, coord.y, slotSize, slotSize,
|
pos.x, pos.y, slotSize, slotSize,
|
||||||
0, 0, 0, region, false, true, tint);
|
0, 0, 0, region, false, true, tint);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -187,8 +188,8 @@ void SlotView::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
auto font = assets->getFont("normal");
|
auto font = assets->getFont("normal");
|
||||||
std::wstring text = std::to_wstring(stack.getCount());
|
std::wstring text = std::to_wstring(stack.getCount());
|
||||||
|
|
||||||
int x = coord.x+slotSize-text.length()*8;
|
int x = pos.x+slotSize-text.length()*8;
|
||||||
int y = coord.y+slotSize-16;
|
int y = pos.y+slotSize-16;
|
||||||
|
|
||||||
batch->setColor(glm::vec4(0, 0, 0, 1.0f));
|
batch->setColor(glm::vec4(0, 0, 0, 1.0f));
|
||||||
font->draw(batch, text, x+1, y+1);
|
font->draw(batch, text, x+1, y+1);
|
||||||
@ -259,7 +260,7 @@ void SlotView::clicked(gui::GUI* gui, mousecode button) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlotView::focus(gui::GUI* gui) {
|
void SlotView::onFocus(gui::GUI* gui) {
|
||||||
clicked(gui, mousecode::BUTTON_1);
|
clicked(gui, mousecode::BUTTON_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +281,7 @@ const SlotLayout& SlotView::getLayout() const {
|
|||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryView::InventoryView() : Container(glm::vec2(), glm::vec2()) {
|
InventoryView::InventoryView() : Container(glm::vec2()) {
|
||||||
setColor(glm::vec4(0, 0, 0, 0.0f));
|
setColor(glm::vec4(0, 0, 0, 0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,13 +292,13 @@ std::shared_ptr<SlotView> InventoryView::addSlot(SlotLayout layout) {
|
|||||||
uint width = InventoryView::SLOT_SIZE + layout.padding;
|
uint width = InventoryView::SLOT_SIZE + layout.padding;
|
||||||
uint height = InventoryView::SLOT_SIZE + layout.padding;
|
uint height = InventoryView::SLOT_SIZE + layout.padding;
|
||||||
|
|
||||||
auto coord = layout.position;
|
auto pos = layout.position;
|
||||||
auto vsize = getSize();
|
auto vsize = getSize();
|
||||||
if (coord.x + width > vsize.x) {
|
if (pos.x + width > vsize.x) {
|
||||||
vsize.x = coord.x + width;
|
vsize.x = pos.x + width;
|
||||||
}
|
}
|
||||||
if (coord.y + height > vsize.y) {
|
if (pos.y + height > vsize.y) {
|
||||||
vsize.y = coord.y + height;
|
vsize.y = pos.y + height;
|
||||||
}
|
}
|
||||||
setSize(vsize);
|
setSize(vsize);
|
||||||
|
|
||||||
@ -337,6 +338,12 @@ void InventoryView::bind(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InventoryView::unbind() {
|
||||||
|
if (inventory->isVirtual()) {
|
||||||
|
frontend->getLevel()->inventories->remove(inventory->getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InventoryView::setSelected(int index) {
|
void InventoryView::setSelected(int index) {
|
||||||
for (int i = 0; i < int(slots.size()); i++) {
|
for (int i = 0; i < int(slots.size()); i++) {
|
||||||
auto slot = slots[i];
|
auto slot = slots[i];
|
||||||
@ -344,8 +351,8 @@ void InventoryView::setSelected(int index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryView::setCoord(glm::vec2 coord) {
|
void InventoryView::setPos(glm::vec2 pos) {
|
||||||
Container::setCoord(coord - origin);
|
Container::setPos(pos - origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryView::setOrigin(glm::vec2 origin) {
|
void InventoryView::setOrigin(glm::vec2 origin) {
|
||||||
@ -378,8 +385,8 @@ static void readSlot(InventoryView* view, gui::UiXmlReader& reader, xml::xmlelem
|
|||||||
int index = element->attr("index", "0").asInt();
|
int index = element->attr("index", "0").asInt();
|
||||||
bool itemSource = element->attr("item-source", "false").asBool();
|
bool itemSource = element->attr("item-source", "false").asBool();
|
||||||
SlotLayout layout(index, glm::vec2(), true, itemSource, nullptr, nullptr);
|
SlotLayout layout(index, glm::vec2(), true, itemSource, nullptr, nullptr);
|
||||||
if (element->has("coord")) {
|
if (element->has("pos")) {
|
||||||
layout.position = element->attr("coord").asVec2();
|
layout.position = element->attr("pos").asVec2();
|
||||||
}
|
}
|
||||||
if (element->has("sharefunc")) {
|
if (element->has("sharefunc")) {
|
||||||
layout.shareFunc = readSlotFunc(view, reader, element, "sharefunc");
|
layout.shareFunc = readSlotFunc(view, reader, element, "sharefunc");
|
||||||
|
|||||||
@ -73,7 +73,7 @@ public:
|
|||||||
bool isHighlighted() const;
|
bool isHighlighted() const;
|
||||||
|
|
||||||
virtual void clicked(gui::GUI*, mousecode) override;
|
virtual void clicked(gui::GUI*, mousecode) override;
|
||||||
virtual void focus(gui::GUI*) override;
|
virtual void onFocus(gui::GUI*) override;
|
||||||
|
|
||||||
void bind(
|
void bind(
|
||||||
int64_t inventoryid,
|
int64_t inventoryid,
|
||||||
@ -101,7 +101,7 @@ public:
|
|||||||
|
|
||||||
void setInventory(std::shared_ptr<Inventory> inventory);
|
void setInventory(std::shared_ptr<Inventory> inventory);
|
||||||
|
|
||||||
virtual void setCoord(glm::vec2 coord) override;
|
virtual void setPos(glm::vec2 pos) override;
|
||||||
|
|
||||||
void setOrigin(glm::vec2 origin);
|
void setOrigin(glm::vec2 origin);
|
||||||
glm::vec2 getOrigin() const;
|
glm::vec2 getOrigin() const;
|
||||||
@ -114,6 +114,8 @@ public:
|
|||||||
InventoryInteraction* interaction
|
InventoryInteraction* interaction
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void unbind();
|
||||||
|
|
||||||
std::shared_ptr<SlotView> addSlot(SlotLayout layout);
|
std::shared_ptr<SlotView> addSlot(SlotLayout layout);
|
||||||
|
|
||||||
std::shared_ptr<Inventory> getInventory() const;
|
std::shared_ptr<Inventory> getInventory() const;
|
||||||
@ -133,7 +135,7 @@ public:
|
|||||||
|
|
||||||
void addGrid(
|
void addGrid(
|
||||||
int cols, int count,
|
int cols, int count,
|
||||||
glm::vec2 coord,
|
glm::vec2 pos,
|
||||||
int padding,
|
int padding,
|
||||||
bool addpanel,
|
bool addpanel,
|
||||||
SlotLayout slotLayout
|
SlotLayout slotLayout
|
||||||
|
|||||||
148
src/frontend/debug_panel.cpp
Normal file
148
src/frontend/debug_panel.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "gui/controls.h"
|
||||||
|
#include "../graphics/Mesh.h"
|
||||||
|
#include "../objects/Player.h"
|
||||||
|
#include "../physics/Hitbox.h"
|
||||||
|
#include "../world/Level.h"
|
||||||
|
#include "../world/World.h"
|
||||||
|
#include "../voxels/Chunks.h"
|
||||||
|
#include "../voxels/Block.h"
|
||||||
|
#include "../util/stringutil.h"
|
||||||
|
#include "../delegates.h"
|
||||||
|
#include "../engine.h"
|
||||||
|
|
||||||
|
#include "WorldRenderer.h"
|
||||||
|
|
||||||
|
using namespace gui;
|
||||||
|
|
||||||
|
static std::shared_ptr<Label> create_label(wstringsupplier supplier) {
|
||||||
|
auto label = std::make_shared<Label>(L"-");
|
||||||
|
label->textSupplier(supplier);
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<UINode> create_debug_panel(
|
||||||
|
Engine* engine,
|
||||||
|
Level* level,
|
||||||
|
Player* player
|
||||||
|
) {
|
||||||
|
auto panel = std::make_shared<Panel>(glm::vec2(250, 200), glm::vec4(5.0f), 2.0f);
|
||||||
|
panel->setPos(glm::vec2(10, 10));
|
||||||
|
|
||||||
|
static int fps = 0;
|
||||||
|
static int fpsMin = fps;
|
||||||
|
static int fpsMax = fps;
|
||||||
|
static std::wstring fpsString = L"";
|
||||||
|
|
||||||
|
panel->listenInterval(0.016f, [engine]() {
|
||||||
|
fps = 1.0f / engine->getDelta();
|
||||||
|
fpsMin = std::min(fps, fpsMin);
|
||||||
|
fpsMax = std::max(fps, fpsMax);
|
||||||
|
});
|
||||||
|
|
||||||
|
panel->listenInterval(0.5f, []() {
|
||||||
|
fpsString = std::to_wstring(fpsMax)+L" / "+std::to_wstring(fpsMin);
|
||||||
|
fpsMin = fps;
|
||||||
|
fpsMax = fps;
|
||||||
|
});
|
||||||
|
panel->add(create_label([](){ return L"fps: "+fpsString;}));
|
||||||
|
|
||||||
|
panel->add(create_label([](){
|
||||||
|
return L"meshes: " + std::to_wstring(Mesh::meshesCount);
|
||||||
|
}));
|
||||||
|
panel->add(create_label([=](){
|
||||||
|
auto& settings = engine->getSettings();
|
||||||
|
bool culling = settings.graphics.frustumCulling;
|
||||||
|
return L"frustum-culling: "+std::wstring(culling ? L"on" : L"off");
|
||||||
|
}));
|
||||||
|
panel->add(create_label([=]() {
|
||||||
|
return L"chunks: "+std::to_wstring(level->chunks->chunksCount)+
|
||||||
|
L" visible: "+std::to_wstring(level->chunks->visible);
|
||||||
|
}));
|
||||||
|
panel->add(create_label([=](){
|
||||||
|
auto* indices = level->content->getIndices();
|
||||||
|
auto def = indices->getBlockDef(player->selectedVoxel.id);
|
||||||
|
std::wstringstream stream;
|
||||||
|
stream << std::hex << player->selectedVoxel.states;
|
||||||
|
if (def) {
|
||||||
|
stream << L" (" << util::str2wstr_utf8(def->name) << L")";
|
||||||
|
}
|
||||||
|
return L"block: "+std::to_wstring(player->selectedVoxel.id)+
|
||||||
|
L" "+stream.str();
|
||||||
|
}));
|
||||||
|
panel->add(create_label([=](){
|
||||||
|
return L"seed: "+std::to_wstring(level->world->getSeed());
|
||||||
|
}));
|
||||||
|
|
||||||
|
for (int ax = 0; ax < 3; ax++) {
|
||||||
|
auto sub = std::make_shared<Container>(glm::vec2(250, 27));
|
||||||
|
|
||||||
|
std::wstring str = L"x: ";
|
||||||
|
str[0] += ax;
|
||||||
|
auto label = std::make_shared<Label>(str);
|
||||||
|
label->setMargin(glm::vec4(2, 3, 2, 3));
|
||||||
|
label->setSize(glm::vec2(20, 27));
|
||||||
|
sub->add(label);
|
||||||
|
sub->setColor(glm::vec4(0.0f));
|
||||||
|
|
||||||
|
// Coord input
|
||||||
|
auto box = std::make_shared<TextBox>(L"");
|
||||||
|
box->setTextSupplier([=]() {
|
||||||
|
Hitbox* hitbox = player->hitbox.get();
|
||||||
|
return util::to_wstring(hitbox->position[ax], 2);
|
||||||
|
});
|
||||||
|
box->setTextConsumer([=](std::wstring text) {
|
||||||
|
try {
|
||||||
|
glm::vec3 position = player->hitbox->position;
|
||||||
|
position[ax] = std::stoi(text);
|
||||||
|
player->teleport(position);
|
||||||
|
} catch (std::invalid_argument& _){
|
||||||
|
}
|
||||||
|
});
|
||||||
|
box->setOnEditStart([=](){
|
||||||
|
Hitbox* hitbox = player->hitbox.get();
|
||||||
|
box->setText(std::to_wstring(int(hitbox->position[ax])));
|
||||||
|
});
|
||||||
|
box->setSize(glm::vec2(230, 27));
|
||||||
|
|
||||||
|
sub->add(box, glm::vec2(20, 0));
|
||||||
|
panel->add(sub);
|
||||||
|
}
|
||||||
|
panel->add(create_label([=](){
|
||||||
|
int hour, minute, second;
|
||||||
|
timeutil::from_value(level->world->daytime, hour, minute, second);
|
||||||
|
|
||||||
|
std::wstring timeString =
|
||||||
|
util::lfill(std::to_wstring(hour), 2, L'0') + L":" +
|
||||||
|
util::lfill(std::to_wstring(minute), 2, L'0');
|
||||||
|
return L"time: "+timeString;
|
||||||
|
}));
|
||||||
|
{
|
||||||
|
auto bar = std::make_shared<TrackBar>(0.0f, 1.0f, 1.0f, 0.005f, 8);
|
||||||
|
bar->setSupplier([=]() {return level->world->daytime;});
|
||||||
|
bar->setConsumer([=](double val) {level->world->daytime = val;});
|
||||||
|
panel->add(bar);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto bar = std::make_shared<TrackBar>(0.0f, 1.0f, 0.0f, 0.005f, 8);
|
||||||
|
bar->setSupplier([=]() {return WorldRenderer::fog;});
|
||||||
|
bar->setConsumer([=](double val) {WorldRenderer::fog = val;});
|
||||||
|
panel->add(bar);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto checkbox = std::make_shared<FullCheckBox>(
|
||||||
|
L"Show Chunk Borders", glm::vec2(400, 24)
|
||||||
|
);
|
||||||
|
checkbox->setSupplier([=]() {
|
||||||
|
return engine->getSettings().debug.showChunkBorders;
|
||||||
|
});
|
||||||
|
checkbox->setConsumer([=](bool checked) {
|
||||||
|
engine->getSettings().debug.showChunkBorders = checked;
|
||||||
|
});
|
||||||
|
panel->add(checkbox);
|
||||||
|
}
|
||||||
|
panel->refresh();
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
@ -16,7 +16,7 @@
|
|||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
GUI::GUI() {
|
GUI::GUI() {
|
||||||
container = std::make_shared<Container>(glm::vec2(0, 0), glm::vec2(1000));
|
container = std::make_shared<Container>(glm::vec2(1000));
|
||||||
uicamera = std::make_unique<Camera>(glm::vec3(), Window::height);
|
uicamera = std::make_unique<Camera>(glm::vec3(), Window::height);
|
||||||
uicamera->perspective = false;
|
uicamera->perspective = false;
|
||||||
uicamera->flipped = true;
|
uicamera->flipped = true;
|
||||||
@ -58,7 +58,7 @@ void GUI::actMouse(float delta) {
|
|||||||
}
|
}
|
||||||
if (focus != pressed) {
|
if (focus != pressed) {
|
||||||
focus = pressed;
|
focus = pressed;
|
||||||
focus->focus(this);
|
focus->onFocus(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ void GUI::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
auto& viewport = pctx->getViewport();
|
auto& viewport = pctx->getViewport();
|
||||||
glm::vec2 wsize = viewport.size();
|
glm::vec2 wsize = viewport.size();
|
||||||
|
|
||||||
menu->setCoord((wsize - menu->getSize()) / 2.0f);
|
menu->setPos((wsize - menu->getSize()) / 2.0f);
|
||||||
uicamera->setFov(wsize.y);
|
uicamera->setFov(wsize.y);
|
||||||
|
|
||||||
Shader* uishader = assets->getShader("ui");
|
Shader* uishader = assets->getShader("ui");
|
||||||
@ -175,7 +175,7 @@ void GUI::setFocus(std::shared_ptr<UINode> node) {
|
|||||||
}
|
}
|
||||||
focus = node;
|
focus = node;
|
||||||
if (focus) {
|
if (focus) {
|
||||||
focus->focus(this);
|
focus->onFocus(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,7 +51,7 @@ namespace gui {
|
|||||||
class Container;
|
class Container;
|
||||||
class PagesControl;
|
class PagesControl;
|
||||||
|
|
||||||
/** The main UI controller */
|
/// @brief The main UI controller
|
||||||
class GUI {
|
class GUI {
|
||||||
std::shared_ptr<Container> container;
|
std::shared_ptr<Container> container;
|
||||||
std::shared_ptr<UINode> hover = nullptr;
|
std::shared_ptr<UINode> hover = nullptr;
|
||||||
@ -67,55 +67,58 @@ namespace gui {
|
|||||||
GUI();
|
GUI();
|
||||||
~GUI();
|
~GUI();
|
||||||
|
|
||||||
/** Get the main menu (PagesControl) node */
|
/// @brief Get the main menu (PagesControl) node
|
||||||
std::shared_ptr<PagesControl> getMenu();
|
std::shared_ptr<PagesControl> getMenu();
|
||||||
|
|
||||||
/** Get current focused node
|
/// @brief Get current focused node
|
||||||
* @return focused node or nullptr */
|
/// @return focused node or nullptr
|
||||||
std::shared_ptr<UINode> getFocused() const;
|
std::shared_ptr<UINode> getFocused() const;
|
||||||
|
|
||||||
/** Check if all user input is caught by some element like TextBox */
|
/// @brief Check if all user input is caught by some element like TextBox
|
||||||
bool isFocusCaught() const;
|
bool isFocusCaught() const;
|
||||||
|
|
||||||
/** Main input handling and logic update method
|
/// @brief Main input handling and logic update method
|
||||||
* @param delta delta time */
|
/// @param delta delta time
|
||||||
void act(float delta);
|
void act(float delta);
|
||||||
|
|
||||||
/** Draw all visible elements on main container
|
/// @brief Draw all visible elements on main container
|
||||||
* @param pctx parent graphics context
|
/// @param pctx parent graphics context
|
||||||
* @param assets active assets storage */
|
/// @param assets active assets storage
|
||||||
void draw(const GfxContext* pctx, Assets* assets);
|
void draw(const GfxContext* pctx, Assets* assets);
|
||||||
|
|
||||||
/** Add node to the main container */
|
/// @brief Add element to the main container
|
||||||
|
/// @param node UI element
|
||||||
void add(std::shared_ptr<UINode> node);
|
void add(std::shared_ptr<UINode> node);
|
||||||
|
|
||||||
/** Remove node from the main container */
|
/// @brief Add element to the main container
|
||||||
|
/// @param node UI element
|
||||||
|
/// @param coord element position within the main container
|
||||||
|
void add(std::shared_ptr<UINode> node, glm::vec2 coord);
|
||||||
|
|
||||||
|
/// @brief Remove node from the main container
|
||||||
void remove(std::shared_ptr<UINode> node) noexcept;
|
void remove(std::shared_ptr<UINode> node) noexcept;
|
||||||
|
|
||||||
/** Store node in the GUI nodes dictionary
|
/// @brief Store node in the GUI nodes dictionary
|
||||||
* (does not add node to the main container)
|
/// (does not add node to the main container)
|
||||||
* @param name node key
|
/// @param name node key
|
||||||
* @param node target node
|
/// @param node target node
|
||||||
*/
|
|
||||||
void store(std::string name, std::shared_ptr<UINode> node);
|
void store(std::string name, std::shared_ptr<UINode> node);
|
||||||
|
|
||||||
/** Get node from the GUI nodes dictionary
|
/// @brief Get node from the GUI nodes dictionary
|
||||||
* @param name node key
|
/// @param name node key
|
||||||
* @return stored node or nullptr
|
/// @return stored node or nullptr
|
||||||
*/
|
|
||||||
std::shared_ptr<UINode> get(std::string name) noexcept;
|
std::shared_ptr<UINode> get(std::string name) noexcept;
|
||||||
|
|
||||||
/** Remove node from the GUI nodes dictionary
|
/// @brief Remove node from the GUI nodes dictionary
|
||||||
* @param name node key
|
/// @param name node key
|
||||||
*/
|
|
||||||
void remove(std::string name) noexcept;
|
void remove(std::string name) noexcept;
|
||||||
|
|
||||||
/** Set node as focused
|
/// @brief Set node as focused
|
||||||
* @param node new focused node or nullptr to remove focus
|
/// @param node new focused node or nullptr to remove focus
|
||||||
*/
|
|
||||||
void setFocus(std::shared_ptr<UINode> node);
|
void setFocus(std::shared_ptr<UINode> node);
|
||||||
|
|
||||||
/** Get the main container */
|
/// @brief Get the main container
|
||||||
|
/// @deprecated
|
||||||
std::shared_ptr<Container> getContainer() const;
|
std::shared_ptr<Container> getContainer() const;
|
||||||
|
|
||||||
void postRunnable(runnable callback);
|
void postRunnable(runnable callback);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
using gui::UINode;
|
using gui::UINode;
|
||||||
using gui::Align;
|
using gui::Align;
|
||||||
|
|
||||||
UINode::UINode(glm::vec2 coord, glm::vec2 size) : coord(coord), size(size) {
|
UINode::UINode(glm::vec2 size) : size(size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
UINode::~UINode() {
|
UINode::~UINode() {
|
||||||
@ -63,18 +63,18 @@ bool UINode::isFocused() const {
|
|||||||
return focused;
|
return focused;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UINode::isInside(glm::vec2 pos) {
|
bool UINode::isInside(glm::vec2 point) {
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
glm::vec2 size = getSize();
|
glm::vec2 size = getSize();
|
||||||
return (pos.x >= coord.x && pos.y >= coord.y &&
|
return (point.x >= pos.x && point.y >= pos.y &&
|
||||||
pos.x < coord.x + size.x && pos.y < coord.y + size.y);
|
point.x < pos.x + size.x && point.y < pos.y + size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<UINode> UINode::getAt(glm::vec2 pos, std::shared_ptr<UINode> self) {
|
std::shared_ptr<UINode> UINode::getAt(glm::vec2 point, std::shared_ptr<UINode> self) {
|
||||||
if (!interactive) {
|
if (!interactive) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return isInside(pos) ? self : nullptr;
|
return isInside(point) ? self : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UINode::isInteractive() const {
|
bool UINode::isInteractive() const {
|
||||||
@ -93,11 +93,11 @@ bool UINode::isResizing() const {
|
|||||||
return resizing;
|
return resizing;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 UINode::calcCoord() const {
|
glm::vec2 UINode::calcPos() const {
|
||||||
if (parent) {
|
if (parent) {
|
||||||
return coord + parent->calcCoord() + parent->contentOffset();
|
return pos + parent->calcPos() + parent->contentOffset();
|
||||||
}
|
}
|
||||||
return coord;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::scrolled(int value) {
|
void UINode::scrolled(int value) {
|
||||||
@ -106,12 +106,12 @@ void UINode::scrolled(int value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::setCoord(glm::vec2 coord) {
|
void UINode::setPos(glm::vec2 pos) {
|
||||||
this->coord = coord;
|
this->pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 UINode::getCoord() const {
|
glm::vec2 UINode::getPos() const {
|
||||||
return coord;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 UINode::getSize() const {
|
glm::vec2 UINode::getSize() const {
|
||||||
@ -187,6 +187,53 @@ const std::string& UINode::getId() const {
|
|||||||
|
|
||||||
void UINode::reposition() {
|
void UINode::reposition() {
|
||||||
if (positionfunc) {
|
if (positionfunc) {
|
||||||
setCoord(positionfunc());
|
setPos(positionfunc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::setGravity(Gravity gravity) {
|
||||||
|
if (gravity == Gravity::none) {
|
||||||
|
setPositionFunc(nullptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPositionFunc([this, gravity](){
|
||||||
|
auto parent = getParent();
|
||||||
|
if (parent == nullptr) {
|
||||||
|
return getPos();
|
||||||
|
}
|
||||||
|
glm::vec4 margin = getMargin();
|
||||||
|
glm::vec2 size = getSize();
|
||||||
|
glm::vec2 parentSize = parent->getSize();
|
||||||
|
|
||||||
|
float x = 0.0f, y = 0.0f;
|
||||||
|
switch (gravity) {
|
||||||
|
case Gravity::top_left:
|
||||||
|
case Gravity::center_left:
|
||||||
|
case Gravity::bottom_left: x = parentSize.x+margin.x; break;
|
||||||
|
case Gravity::top_center:
|
||||||
|
case Gravity::center_center:
|
||||||
|
case Gravity::bottom_center: x = (parentSize.x-size.x)/2.0f; break;
|
||||||
|
case Gravity::top_right:
|
||||||
|
case Gravity::center_right:
|
||||||
|
case Gravity::bottom_right: x = parentSize.x-size.x-margin.z; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
switch (gravity) {
|
||||||
|
case Gravity::top_left:
|
||||||
|
case Gravity::top_center:
|
||||||
|
case Gravity::top_right: y = parentSize.y+margin.y; break;
|
||||||
|
case Gravity::center_left:
|
||||||
|
case Gravity::center_center:
|
||||||
|
case Gravity::center_right: y = (parentSize.y-size.y)/2.0f; break;
|
||||||
|
case Gravity::bottom_left:
|
||||||
|
case Gravity::bottom_center:
|
||||||
|
case Gravity::bottom_right: y = parentSize.y-size.y-margin.w; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return glm::vec2(x, y);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (parent) {
|
||||||
|
reposition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,34 +24,66 @@ namespace gui {
|
|||||||
top=left, bottom=right,
|
top=left, bottom=right,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Gravity {
|
||||||
|
none,
|
||||||
|
|
||||||
|
top_left,
|
||||||
|
top_center,
|
||||||
|
top_right,
|
||||||
|
|
||||||
|
center_left,
|
||||||
|
center_center,
|
||||||
|
center_right,
|
||||||
|
|
||||||
|
bottom_left,
|
||||||
|
bottom_center,
|
||||||
|
bottom_right
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @brief Base abstract class for all UI elements
|
||||||
class UINode {
|
class UINode {
|
||||||
/**
|
/// @brief element identifier used for direct access in UiDocument
|
||||||
* element identifier used for direct access in UiDocument
|
|
||||||
*/
|
|
||||||
std::string id = "";
|
std::string id = "";
|
||||||
protected:
|
protected:
|
||||||
glm::vec2 coord;
|
/// @brief element position within the parent element
|
||||||
|
glm::vec2 pos {0.0f};
|
||||||
|
/// @brief element size (width, height)
|
||||||
glm::vec2 size;
|
glm::vec2 size;
|
||||||
|
/// @brief minimal element size
|
||||||
glm::vec2 minSize {1.0f};
|
glm::vec2 minSize {1.0f};
|
||||||
|
/// @brief element primary color (background-color or text-color if label)
|
||||||
glm::vec4 color {1.0f};
|
glm::vec4 color {1.0f};
|
||||||
|
/// @brief element color when mouse is over it
|
||||||
glm::vec4 hoverColor {1.0f};
|
glm::vec4 hoverColor {1.0f};
|
||||||
|
/// @brief element margin (only supported for Panel sub-nodes)
|
||||||
glm::vec4 margin {1.0f};
|
glm::vec4 margin {1.0f};
|
||||||
|
/// @brief is element visible
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
|
/// @brief is mouse over the element
|
||||||
bool hover = false;
|
bool hover = false;
|
||||||
|
/// @brief is mouse has been pressed over the element and not released yet
|
||||||
bool pressed = false;
|
bool pressed = false;
|
||||||
|
/// @brief is element focused
|
||||||
bool focused = false;
|
bool focused = false;
|
||||||
|
/// @brief is element opaque for cursor interaction
|
||||||
bool interactive = true;
|
bool interactive = true;
|
||||||
|
/// @brief does the element support resizing by parent elements
|
||||||
bool resizing = true;
|
bool resizing = true;
|
||||||
|
/// @brief z-index property specifies the stack order of an element
|
||||||
int zindex = 0;
|
int zindex = 0;
|
||||||
|
/// @brief element content alignment (supported by Label only)
|
||||||
Align align = Align::left;
|
Align align = Align::left;
|
||||||
|
/// @brief parent element
|
||||||
UINode* parent = nullptr;
|
UINode* parent = nullptr;
|
||||||
|
/// @brief position supplier for the element (called on parent element size update)
|
||||||
vec2supplier positionfunc = nullptr;
|
vec2supplier positionfunc = nullptr;
|
||||||
UINode(glm::vec2 coord, glm::vec2 size);
|
|
||||||
|
UINode(glm::vec2 size);
|
||||||
public:
|
public:
|
||||||
virtual ~UINode();
|
virtual ~UINode();
|
||||||
/** Called every frame for all visible elements
|
|
||||||
* @param delta delta time
|
/// @brief Called every frame for all visible elements
|
||||||
*/
|
/// @param delta delta timУ
|
||||||
virtual void act(float delta) {};
|
virtual void act(float delta) {};
|
||||||
virtual void draw(const GfxContext* pctx, Assets* assets) = 0;
|
virtual void draw(const GfxContext* pctx, Assets* assets) = 0;
|
||||||
|
|
||||||
@ -67,11 +99,12 @@ namespace gui {
|
|||||||
virtual void setParent(UINode* node);
|
virtual void setParent(UINode* node);
|
||||||
UINode* getParent() const;
|
UINode* getParent() const;
|
||||||
|
|
||||||
/** Set element color (doesn't affect inner elements).
|
/// @brief Set element color (doesn't affect inner elements).
|
||||||
Also replaces hover color to avoid adding extra properties. */
|
/// Also replaces hover color to avoid adding extra properties
|
||||||
virtual void setColor(glm::vec4 newColor);
|
virtual void setColor(glm::vec4 newColor);
|
||||||
|
|
||||||
/** Get element color (float R,G,B,A in range [0.0, 1.0])*/
|
/// @brief Get element color
|
||||||
|
/// @return (float R,G,B,A in range [0.0, 1.0])
|
||||||
glm::vec4 getColor() const;
|
glm::vec4 getColor() const;
|
||||||
|
|
||||||
virtual void setHoverColor(glm::vec4 newColor);
|
virtual void setHoverColor(glm::vec4 newColor);
|
||||||
@ -80,12 +113,14 @@ namespace gui {
|
|||||||
virtual void setMargin(glm::vec4 margin);
|
virtual void setMargin(glm::vec4 margin);
|
||||||
glm::vec4 getMargin() const;
|
glm::vec4 getMargin() const;
|
||||||
|
|
||||||
/** Influences container elements sort order
|
/// @brief Specifies the stack order of an element
|
||||||
Doesn't work in Panel */
|
/// @attention Is not supported by Panel
|
||||||
virtual void setZIndex(int idx);
|
virtual void setZIndex(int idx);
|
||||||
|
|
||||||
|
/// @brief Get element z-index
|
||||||
int getZIndex() const;
|
int getZIndex() const;
|
||||||
|
|
||||||
virtual void focus(GUI*) {focused = true;}
|
virtual void onFocus(GUI*) {focused = true;}
|
||||||
virtual void click(GUI*, int x, int y);
|
virtual void click(GUI*, int x, int y);
|
||||||
virtual void clicked(GUI*, mousecode button) {}
|
virtual void clicked(GUI*, mousecode button) {}
|
||||||
virtual void mouseMove(GUI*, int x, int y) {};
|
virtual void mouseMove(GUI*, int x, int y) {};
|
||||||
@ -123,9 +158,9 @@ namespace gui {
|
|||||||
/* Get inner content offset. Used for scroll */
|
/* Get inner content offset. Used for scroll */
|
||||||
virtual glm::vec2 contentOffset() {return glm::vec2(0.0f);};
|
virtual glm::vec2 contentOffset() {return glm::vec2(0.0f);};
|
||||||
/* Calculate screen position of the element */
|
/* Calculate screen position of the element */
|
||||||
virtual glm::vec2 calcCoord() const;
|
virtual glm::vec2 calcPos() const;
|
||||||
virtual void setCoord(glm::vec2 coord);
|
virtual void setPos(glm::vec2 pos);
|
||||||
virtual glm::vec2 getCoord() const;
|
virtual glm::vec2 getPos() const;
|
||||||
virtual glm::vec2 getSize() const;
|
virtual glm::vec2 getSize() const;
|
||||||
virtual void setSize(glm::vec2 size);
|
virtual void setSize(glm::vec2 size);
|
||||||
virtual glm::vec2 getMinSize() const;
|
virtual glm::vec2 getMinSize() const;
|
||||||
@ -140,8 +175,10 @@ namespace gui {
|
|||||||
void setId(const std::string& id);
|
void setId(const std::string& id);
|
||||||
const std::string& getId() const;
|
const std::string& getId() const;
|
||||||
|
|
||||||
/* Fetch coord from positionfunc if assigned */
|
/* Fetch pos from positionfunc if assigned */
|
||||||
void reposition();
|
void reposition();
|
||||||
|
|
||||||
|
virtual void setGravity(Gravity gravity);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
Container::Container(glm::vec2 coord, glm::vec2 size) : UINode(coord, size) {
|
Container::Container(glm::vec2 size) : UINode(size) {
|
||||||
actualLength = size.y;
|
actualLength = size.y;
|
||||||
setColor(glm::vec4());
|
setColor(glm::vec4());
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ void Container::setScrollable(bool flag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Container::draw(const GfxContext* pctx, Assets* assets) {
|
void Container::draw(const GfxContext* pctx, Assets* assets) {
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
glm::vec2 size = getSize();
|
glm::vec2 size = getSize();
|
||||||
drawBackground(pctx, assets);
|
drawBackground(pctx, assets);
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ void Container::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
batch->flush();
|
batch->flush();
|
||||||
{
|
{
|
||||||
GfxContext ctx = pctx->sub();
|
GfxContext ctx = pctx->sub();
|
||||||
ctx.scissors(glm::vec4(coord.x, coord.y, size.x, size.y));
|
ctx.scissors(glm::vec4(pos.x, pos.y, size.x, size.y));
|
||||||
for (auto node : nodes) {
|
for (auto node : nodes) {
|
||||||
if (node->isVisible())
|
if (node->isVisible())
|
||||||
node->draw(pctx, assets);
|
node->draw(pctx, assets);
|
||||||
@ -100,12 +100,12 @@ void Container::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
void Container::drawBackground(const GfxContext* pctx, Assets* assets) {
|
void Container::drawBackground(const GfxContext* pctx, Assets* assets) {
|
||||||
if (color.a <= 0.0f)
|
if (color.a <= 0.0f)
|
||||||
return;
|
return;
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
|
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
batch->setColor(color);
|
batch->setColor(color);
|
||||||
batch->rect(coord.x, coord.y, size.x, size.y);
|
batch->rect(pos.x, pos.y, size.x, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::add(std::shared_ptr<UINode> node) {
|
void Container::add(std::shared_ptr<UINode> node) {
|
||||||
@ -115,8 +115,8 @@ void Container::add(std::shared_ptr<UINode> node) {
|
|||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::add(std::shared_ptr<UINode> node, glm::vec2 coord) {
|
void Container::add(std::shared_ptr<UINode> node, glm::vec2 pos) {
|
||||||
node->setCoord(coord);
|
node->setPos(pos);
|
||||||
add(node);
|
add(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,9 +157,10 @@ const std::vector<std::shared_ptr<UINode>>& Container::getNodes() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Panel::Panel(glm::vec2 size, glm::vec4 padding, float interval)
|
Panel::Panel(glm::vec2 size, glm::vec4 padding, float interval)
|
||||||
: Container(glm::vec2(), size),
|
: Container(size),
|
||||||
padding(padding),
|
padding(padding),
|
||||||
interval(interval) {
|
interval(interval)
|
||||||
|
{
|
||||||
setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.75f));
|
setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.75f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +211,7 @@ void Panel::refresh() {
|
|||||||
y += margin.y;
|
y += margin.y;
|
||||||
|
|
||||||
float ex = x + margin.x;
|
float ex = x + margin.x;
|
||||||
node->setCoord(glm::vec2(ex, y));
|
node->setPos(glm::vec2(ex, y));
|
||||||
y += nodesize.y + margin.w + interval;
|
y += nodesize.y + margin.w + interval;
|
||||||
|
|
||||||
float width = size.x - padding.x - padding.z - margin.x - margin.z;
|
float width = size.x - padding.x - padding.z - margin.x - margin.z;
|
||||||
@ -227,7 +228,7 @@ void Panel::refresh() {
|
|||||||
glm::vec2 nodesize = node->getSize();
|
glm::vec2 nodesize = node->getSize();
|
||||||
const glm::vec4 margin = node->getMargin();
|
const glm::vec4 margin = node->getMargin();
|
||||||
x += margin.x;
|
x += margin.x;
|
||||||
node->setCoord(glm::vec2(x, y+margin.y));
|
node->setPos(glm::vec2(x, y+margin.y));
|
||||||
x += nodesize.x + margin.z + interval;
|
x += nodesize.x + margin.z + interval;
|
||||||
|
|
||||||
node->refresh();
|
node->refresh();
|
||||||
@ -245,7 +246,7 @@ Orientation Panel::getOrientation() const {
|
|||||||
return orientation;
|
return orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
PagesControl::PagesControl() : Container(glm::vec2(), glm::vec2(1)){
|
PagesControl::PagesControl() : Container(glm::vec2(1)){
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PagesControl::has(std::string name) {
|
bool PagesControl::has(std::string name) {
|
||||||
|
|||||||
@ -33,14 +33,14 @@ namespace gui {
|
|||||||
int actualLength = 0;
|
int actualLength = 0;
|
||||||
bool scrollable = true;
|
bool scrollable = true;
|
||||||
public:
|
public:
|
||||||
Container(glm::vec2 coord, glm::vec2 size);
|
Container(glm::vec2 size);
|
||||||
|
|
||||||
virtual void act(float delta) override;
|
virtual void act(float delta) override;
|
||||||
virtual void drawBackground(const GfxContext* pctx, Assets* assets);
|
virtual void drawBackground(const GfxContext* pctx, Assets* assets);
|
||||||
virtual void draw(const GfxContext* pctx, Assets* assets) override;
|
virtual void draw(const GfxContext* pctx, Assets* assets) override;
|
||||||
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
|
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
|
||||||
virtual void add(std::shared_ptr<UINode> node);
|
virtual void add(std::shared_ptr<UINode> node);
|
||||||
virtual void add(std::shared_ptr<UINode> node, glm::vec2 coord);
|
virtual void add(std::shared_ptr<UINode> node, glm::vec2 pos);
|
||||||
virtual void remove(std::shared_ptr<UINode> node);
|
virtual void remove(std::shared_ptr<UINode> node);
|
||||||
virtual void scrolled(int value) override;
|
virtual void scrolled(int value) override;
|
||||||
virtual void setScrollable(bool flag);
|
virtual void setScrollable(bool flag);
|
||||||
|
|||||||
@ -17,17 +17,19 @@
|
|||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
Label::Label(std::string text, std::string fontName)
|
Label::Label(std::string text, std::string fontName)
|
||||||
: UINode(glm::vec2(), glm::vec2(text.length() * 8, 15)),
|
: UINode(glm::vec2(text.length() * 8, 15)),
|
||||||
text(util::str2wstr_utf8(text)),
|
text(util::str2wstr_utf8(text)),
|
||||||
fontName(fontName) {
|
fontName(fontName)
|
||||||
|
{
|
||||||
setInteractive(false);
|
setInteractive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Label::Label(std::wstring text, std::string fontName)
|
Label::Label(std::wstring text, std::string fontName)
|
||||||
: UINode(glm::vec2(), glm::vec2(text.length() * 8, 15)),
|
: UINode(glm::vec2(text.length() * 8, 15)),
|
||||||
text(text),
|
text(text),
|
||||||
fontName(fontName) {
|
fontName(fontName)
|
||||||
|
{
|
||||||
setInteractive(false);
|
setInteractive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,28 +139,28 @@ void Label::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
(lines == 1 ? lineHeight : lineHeight*lineInterval)*lines + font->getYOffset()
|
(lines == 1 ? lineHeight : lineHeight*lineInterval)*lines + font->getYOffset()
|
||||||
);
|
);
|
||||||
|
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
switch (align) {
|
switch (align) {
|
||||||
case Align::left:
|
case Align::left:
|
||||||
break;
|
break;
|
||||||
case Align::center:
|
case Align::center:
|
||||||
coord.x += (size.x-newsize.x)*0.5f;
|
pos.x += (size.x-newsize.x)*0.5f;
|
||||||
break;
|
break;
|
||||||
case Align::right:
|
case Align::right:
|
||||||
coord.x += size.x-newsize.x;
|
pos.x += size.x-newsize.x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (valign) {
|
switch (valign) {
|
||||||
case Align::top:
|
case Align::top:
|
||||||
break;
|
break;
|
||||||
case Align::center:
|
case Align::center:
|
||||||
coord.y += (size.y-newsize.y)*0.5f;
|
pos.y += (size.y-newsize.y)*0.5f;
|
||||||
break;
|
break;
|
||||||
case Align::bottom:
|
case Align::bottom:
|
||||||
coord.y += size.y-newsize.y;
|
pos.y += size.y-newsize.y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
textYOffset = coord.y-calcCoord().y;
|
textYOffset = pos.y-calcPos().y;
|
||||||
totalLineHeight = lineHeight * lineInterval;
|
totalLineHeight = lineHeight * lineInterval;
|
||||||
|
|
||||||
if (multiline) {
|
if (multiline) {
|
||||||
@ -170,10 +172,10 @@ void Label::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
view = std::wstring_view(text.c_str()+offset, end);
|
view = std::wstring_view(text.c_str()+offset, end);
|
||||||
offset += end + 1;
|
offset += end + 1;
|
||||||
}
|
}
|
||||||
font->draw(batch, view, coord.x, coord.y + i * totalLineHeight, FontStyle::none);
|
font->draw(batch, view, pos.x, pos.y + i * totalLineHeight, FontStyle::none);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
font->draw(batch, text, coord.x, coord.y, FontStyle::none);
|
font->draw(batch, text, pos.x, pos.y, FontStyle::none);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,12 +193,12 @@ bool Label::isMultiline() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ================================= Image ====================================
|
// ================================= Image ====================================
|
||||||
Image::Image(std::string texture, glm::vec2 size) : UINode(glm::vec2(), size), texture(texture) {
|
Image::Image(std::string texture, glm::vec2 size) : UINode(size), texture(texture) {
|
||||||
setInteractive(false);
|
setInteractive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::draw(const GfxContext* pctx, Assets* assets) {
|
void Image::draw(const GfxContext* pctx, Assets* assets) {
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
glm::vec4 color = getColor();
|
glm::vec4 color = getColor();
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
|
|
||||||
@ -206,7 +208,7 @@ void Image::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
}
|
}
|
||||||
batch->texture(texture);
|
batch->texture(texture);
|
||||||
batch->setColor(color);
|
batch->setColor(color);
|
||||||
batch->rect(coord.x, coord.y, size.x, size.y,
|
batch->rect(pos.x, pos.y, size.x, size.y,
|
||||||
0, 0, 0, UVRegion(), false, true, color);
|
0, 0, 0, UVRegion(), false, true, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,11 +296,11 @@ void Button::refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Button::drawBackground(const GfxContext* pctx, Assets* assets) {
|
void Button::drawBackground(const GfxContext* pctx, Assets* assets) {
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
batch->setColor(isPressed() ? pressedColor : (hover ? hoverColor : color));
|
batch->setColor(isPressed() ? pressedColor : (hover ? hoverColor : color));
|
||||||
batch->rect(coord.x, coord.y, size.x, size.y);
|
batch->rect(pos.x, pos.y, size.x, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::mouseRelease(GUI* gui, int x, int y) {
|
void Button::mouseRelease(GUI* gui, int x, int y) {
|
||||||
@ -330,7 +332,7 @@ Align Button::getTextAlign() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================== RichButton ==================================
|
// ============================== RichButton ==================================
|
||||||
RichButton::RichButton(glm::vec2 size) : Container(glm::vec2(), size) {
|
RichButton::RichButton(glm::vec2 size) : Container(size) {
|
||||||
setHoverColor(glm::vec4(0.05f, 0.1f, 0.15f, 0.75f));
|
setHoverColor(glm::vec4(0.05f, 0.1f, 0.15f, 0.75f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,11 +351,11 @@ RichButton* RichButton::listenAction(onaction action) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RichButton::drawBackground(const GfxContext* pctx, Assets* assets) {
|
void RichButton::drawBackground(const GfxContext* pctx, Assets* assets) {
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
batch->setColor(isPressed() ? pressedColor : (hover ? hoverColor : color));
|
batch->setColor(isPressed() ? pressedColor : (hover ? hoverColor : color));
|
||||||
batch->rect(coord.x, coord.y, size.x, size.y);
|
batch->rect(pos.x, pos.y, size.x, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================ TextBox ===================================
|
// ================================ TextBox ===================================
|
||||||
@ -366,7 +368,7 @@ TextBox::TextBox(std::wstring placeholder, glm::vec4 padding)
|
|||||||
add(label);
|
add(label);
|
||||||
setHoverColor(glm::vec4(0.05f, 0.1f, 0.2f, 0.75f));
|
setHoverColor(glm::vec4(0.05f, 0.1f, 0.2f, 0.75f));
|
||||||
|
|
||||||
textInitX = label->getCoord().x;
|
textInitX = label->getPos().x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::draw(const GfxContext* pctx, Assets* assets) {
|
void TextBox::draw(const GfxContext* pctx, Assets* assets) {
|
||||||
@ -377,14 +379,14 @@ void TextBox::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
if (!isFocused())
|
if (!isFocused())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
glm::vec2 size = getSize();
|
glm::vec2 size = getSize();
|
||||||
|
|
||||||
auto subctx = pctx->sub();
|
auto subctx = pctx->sub();
|
||||||
subctx.scissors(glm::vec4(coord.x, coord.y, size.x, size.y));
|
subctx.scissors(glm::vec4(pos.x, pos.y, size.x, size.y));
|
||||||
|
|
||||||
const int lineHeight = font->getLineHeight() * label->getLineInterval();
|
const int lineHeight = font->getLineHeight() * label->getLineInterval();
|
||||||
glm::vec2 lcoord = label->calcCoord();
|
glm::vec2 lcoord = label->calcPos();
|
||||||
lcoord.y -= 2;
|
lcoord.y -= 2;
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
@ -420,7 +422,7 @@ void TextBox::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::drawBackground(const GfxContext* pctx, Assets* assets) {
|
void TextBox::drawBackground(const GfxContext* pctx, Assets* assets) {
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
|
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
@ -437,14 +439,14 @@ void TextBox::drawBackground(const GfxContext* pctx, Assets* assets) {
|
|||||||
batch->setColor(invalidColor);
|
batch->setColor(invalidColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
batch->rect(coord.x, coord.y, size.x, size.y);
|
batch->rect(pos.x, pos.y, size.x, size.y);
|
||||||
if (!isFocused() && supplier) {
|
if (!isFocused() && supplier) {
|
||||||
input = supplier();
|
input = supplier();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFocused() && multiline) {
|
if (isFocused() && multiline) {
|
||||||
batch->setColor(glm::vec4(1, 1, 1, 0.1f));
|
batch->setColor(glm::vec4(1, 1, 1, 0.1f));
|
||||||
glm::vec2 lcoord = label->calcCoord();
|
glm::vec2 lcoord = label->calcPos();
|
||||||
lcoord.y -= 2;
|
lcoord.y -= 2;
|
||||||
uint line = label->getLineByTextIndex(caret);
|
uint line = label->getLineByTextIndex(caret);
|
||||||
int lineY = label->getLineYOffset(line);
|
int lineY = label->getLineYOffset(line);
|
||||||
@ -536,7 +538,7 @@ size_t TextBox::getSelectionLength() const {
|
|||||||
/// @brief Set scroll offset
|
/// @brief Set scroll offset
|
||||||
/// @param x scroll offset
|
/// @param x scroll offset
|
||||||
void TextBox::setTextOffset(uint x) {
|
void TextBox::setTextOffset(uint x) {
|
||||||
label->setCoord(glm::vec2(textInitX - int(x), label->getCoord().y));
|
label->setPos(glm::vec2(textInitX - int(x), label->getPos().y));
|
||||||
textOffset = x;
|
textOffset = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,8 +585,8 @@ void TextBox::setOnEditStart(runnable oneditstart) {
|
|||||||
onEditStart = oneditstart;
|
onEditStart = oneditstart;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::focus(GUI* gui) {
|
void TextBox::onFocus(GUI* gui) {
|
||||||
Panel::focus(gui);
|
Panel::onFocus(gui);
|
||||||
if (onEditStart){
|
if (onEditStart){
|
||||||
setCaret(input.size());
|
setCaret(input.size());
|
||||||
onEditStart();
|
onEditStart();
|
||||||
@ -611,7 +613,7 @@ size_t TextBox::normalizeIndex(int index) {
|
|||||||
int TextBox::calcIndexAt(int x, int y) const {
|
int TextBox::calcIndexAt(int x, int y) const {
|
||||||
if (font == nullptr)
|
if (font == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
glm::vec2 lcoord = label->calcCoord();
|
glm::vec2 lcoord = label->calcPos();
|
||||||
uint line = label->getLineByYOffset(y-lcoord.y);
|
uint line = label->getLineByYOffset(y-lcoord.y);
|
||||||
line = std::min(line, label->getLinesNumber()-1);
|
line = std::min(line, label->getLinesNumber()-1);
|
||||||
size_t lineLength = getLineLength(line);
|
size_t lineLength = getLineLength(line);
|
||||||
@ -883,11 +885,11 @@ InputBindBox::InputBindBox(Binding& binding, glm::vec4 padding)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InputBindBox::drawBackground(const GfxContext* pctx, Assets* assets) {
|
void InputBindBox::drawBackground(const GfxContext* pctx, Assets* assets) {
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
batch->setColor(isFocused() ? focusedColor : (hover ? hoverColor : color));
|
batch->setColor(isFocused() ? focusedColor : (hover ? hoverColor : color));
|
||||||
batch->rect(coord.x, coord.y, size.x, size.y);
|
batch->rect(pos.x, pos.y, size.x, size.y);
|
||||||
label->setText(util::str2wstr_utf8(binding.text()));
|
label->setText(util::str2wstr_utf8(binding.text()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -904,17 +906,19 @@ void InputBindBox::keyPressed(keycode key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ================================ TrackBar ==================================
|
// ================================ TrackBar ==================================
|
||||||
TrackBar::TrackBar(double min,
|
TrackBar::TrackBar(
|
||||||
|
double min,
|
||||||
double max,
|
double max,
|
||||||
double value,
|
double value,
|
||||||
double step,
|
double step,
|
||||||
int trackWidth)
|
int trackWidth
|
||||||
: UINode(glm::vec2(), glm::vec2(26)),
|
) : UINode(glm::vec2(26)),
|
||||||
min(min),
|
min(min),
|
||||||
max(max),
|
max(max),
|
||||||
value(value),
|
value(value),
|
||||||
step(step),
|
step(step),
|
||||||
trackWidth(trackWidth) {
|
trackWidth(trackWidth)
|
||||||
|
{
|
||||||
setColor(glm::vec4(0.f, 0.f, 0.f, 0.4f));
|
setColor(glm::vec4(0.f, 0.f, 0.f, 0.4f));
|
||||||
setHoverColor(glm::vec4(0.01f, 0.02f, 0.03f, 0.5f));
|
setHoverColor(glm::vec4(0.01f, 0.02f, 0.03f, 0.5f));
|
||||||
}
|
}
|
||||||
@ -923,18 +927,18 @@ void TrackBar::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
if (supplier) {
|
if (supplier) {
|
||||||
value = supplier();
|
value = supplier();
|
||||||
}
|
}
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
batch->setColor(hover ? hoverColor : color);
|
batch->setColor(hover ? hoverColor : color);
|
||||||
batch->rect(coord.x, coord.y, size.x, size.y);
|
batch->rect(pos.x, pos.y, size.x, size.y);
|
||||||
|
|
||||||
float width = size.x;
|
float width = size.x;
|
||||||
float t = (value - min) / (max-min+trackWidth*step);
|
float t = (value - min) / (max-min+trackWidth*step);
|
||||||
|
|
||||||
batch->setColor(trackColor);
|
batch->setColor(trackColor);
|
||||||
int actualWidth = size.x * (trackWidth / (max-min+trackWidth*step) * step);
|
int actualWidth = size.x * (trackWidth / (max-min+trackWidth*step) * step);
|
||||||
batch->rect(coord.x + width * t, coord.y, actualWidth, size.y);
|
batch->rect(pos.x + width * t, pos.y, actualWidth, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackBar::setSupplier(doublesupplier supplier) {
|
void TrackBar::setSupplier(doublesupplier supplier) {
|
||||||
@ -946,9 +950,9 @@ void TrackBar::setConsumer(doubleconsumer consumer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TrackBar::mouseMove(GUI*, int x, int y) {
|
void TrackBar::mouseMove(GUI*, int x, int y) {
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
value = x;
|
value = x;
|
||||||
value -= coord.x;
|
value -= pos.x;
|
||||||
value = (value)/size.x * (max-min+trackWidth*step);
|
value = (value)/size.x * (max-min+trackWidth*step);
|
||||||
value += min;
|
value += min;
|
||||||
value = (value > max) ? max : value;
|
value = (value > max) ? max : value;
|
||||||
@ -1009,7 +1013,7 @@ void TrackBar::setTrackColor(glm::vec4 color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ================================ CheckBox ==================================
|
// ================================ CheckBox ==================================
|
||||||
CheckBox::CheckBox(bool checked) : UINode(glm::vec2(), glm::vec2(32.0f)), checked(checked) {
|
CheckBox::CheckBox(bool checked) : UINode(glm::vec2(32.0f)), checked(checked) {
|
||||||
setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1017,11 +1021,11 @@ void CheckBox::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
if (supplier) {
|
if (supplier) {
|
||||||
checked = supplier();
|
checked = supplier();
|
||||||
}
|
}
|
||||||
glm::vec2 coord = calcCoord();
|
glm::vec2 pos = calcPos();
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
batch->setColor(checked ? checkColor : (hover ? hoverColor : color));
|
batch->setColor(checked ? checkColor : (hover ? hoverColor : color));
|
||||||
batch->rect(coord.x, coord.y, size.x, size.y);
|
batch->rect(pos.x, pos.y, size.x, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckBox::mouseRelease(GUI*, int x, int y) {
|
void CheckBox::mouseRelease(GUI*, int x, int y) {
|
||||||
|
|||||||
@ -272,7 +272,7 @@ namespace gui {
|
|||||||
/// @brief Set runnable called on textbox focus
|
/// @brief Set runnable called on textbox focus
|
||||||
virtual void setOnEditStart(runnable oneditstart);
|
virtual void setOnEditStart(runnable oneditstart);
|
||||||
|
|
||||||
virtual void focus(GUI*) override;
|
virtual void onFocus(GUI*) override;
|
||||||
virtual void refresh() override;
|
virtual void refresh() override;
|
||||||
virtual void click(GUI*, int, int) override;
|
virtual void click(GUI*, int, int) override;
|
||||||
virtual void mouseMove(GUI*, int x, int y) override;
|
virtual void mouseMove(GUI*, int x, int y) override;
|
||||||
|
|||||||
@ -22,13 +22,32 @@ static Align align_from_string(const std::string& str, Align def) {
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Gravity gravity_from_string(const std::string& str) {
|
||||||
|
static const std::unordered_map<std::string, Gravity> gravity_names {
|
||||||
|
{"top-left", Gravity::top_left},
|
||||||
|
{"top-center", Gravity::top_center},
|
||||||
|
{"top-right", Gravity::top_right},
|
||||||
|
{"center-left", Gravity::center_left},
|
||||||
|
{"center-center", Gravity::center_center},
|
||||||
|
{"center-right", Gravity::center_right},
|
||||||
|
{"bottom-left", Gravity::bottom_left},
|
||||||
|
{"bottom-center", Gravity::bottom_center},
|
||||||
|
{"bottom-right", Gravity::bottom_right},
|
||||||
|
};
|
||||||
|
auto found = gravity_names.find(str);
|
||||||
|
if (found == gravity_names.end()) {
|
||||||
|
return found->second;
|
||||||
|
}
|
||||||
|
return Gravity::none;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read basic UINode properties */
|
/* Read basic UINode properties */
|
||||||
static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) {
|
static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) {
|
||||||
if (element->has("id")) {
|
if (element->has("id")) {
|
||||||
node.setId(element->attr("id").getText());
|
node.setId(element->attr("id").getText());
|
||||||
}
|
}
|
||||||
if (element->has("pos")) {
|
if (element->has("pos")) {
|
||||||
node.setCoord(element->attr("pos").asVec2());
|
node.setPos(element->attr("pos").asVec2());
|
||||||
}
|
}
|
||||||
if (element->has("size")) {
|
if (element->has("size")) {
|
||||||
node.setSize(element->attr("size").asVec2());
|
node.setSize(element->attr("size").asVec2());
|
||||||
@ -67,6 +86,12 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no
|
|||||||
}
|
}
|
||||||
std::string alignName = element->attr("align", "").getText();
|
std::string alignName = element->attr("align", "").getText();
|
||||||
node.setAlign(align_from_string(alignName, node.getAlign()));
|
node.setAlign(align_from_string(alignName, node.getAlign()));
|
||||||
|
|
||||||
|
if (element->has("gravity")) {
|
||||||
|
node.setGravity(gravity_from_string(
|
||||||
|
element->attr("gravity").getText()
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -149,7 +174,7 @@ static std::shared_ptr<UINode> readLabel(UiXmlReader& reader, xml::xmlelement el
|
|||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readContainer(UiXmlReader& reader, xml::xmlelement element) {
|
static std::shared_ptr<UINode> readContainer(UiXmlReader& reader, xml::xmlelement element) {
|
||||||
auto container = std::make_shared<Container>(glm::vec2(), glm::vec2());
|
auto container = std::make_shared<Container>(glm::vec2());
|
||||||
_readContainer(reader, element, *container);
|
_readContainer(reader, element, *container);
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,11 @@
|
|||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
|
|
||||||
// TODO: refactor this garbage
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <GL/glew.h>
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
#include "../content/Content.h"
|
#include "../content/Content.h"
|
||||||
@ -55,14 +51,51 @@
|
|||||||
#include "../items/Inventories.h"
|
#include "../items/Inventories.h"
|
||||||
#include "../logic/scripting/scripting.h"
|
#include "../logic/scripting/scripting.h"
|
||||||
|
|
||||||
using namespace gui;
|
|
||||||
|
|
||||||
static std::shared_ptr<Label> create_label(wstringsupplier supplier) {
|
// implemented in debug_panel.cpp
|
||||||
auto label = std::make_shared<Label>(L"-");
|
extern std::shared_ptr<gui::UINode> create_debug_panel(
|
||||||
label->textSupplier(supplier);
|
Engine* engine,
|
||||||
return label;
|
Level* level,
|
||||||
|
Player* player
|
||||||
|
);
|
||||||
|
|
||||||
|
class DeltaGrapher : public gui::UINode {
|
||||||
|
std::unique_ptr<int[]> points;
|
||||||
|
float multiplier;
|
||||||
|
int index = 0;
|
||||||
|
int dmwidth;
|
||||||
|
int dmheight;
|
||||||
|
public:
|
||||||
|
DeltaGrapher(uint width, uint height, float multiplier)
|
||||||
|
: gui::UINode(glm::vec2(width, height)),
|
||||||
|
multiplier(multiplier),
|
||||||
|
dmwidth(width),
|
||||||
|
dmheight(height)
|
||||||
|
{
|
||||||
|
points = std::make_unique<int[]>(width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void act(float delta) override {
|
||||||
|
index = index + 1 % dmwidth;
|
||||||
|
int value = static_cast<int>(delta * multiplier);
|
||||||
|
points[index % dmwidth] = std::min(value, dmheight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(const GfxContext* pctx, Assets* assets) override {
|
||||||
|
glm::vec2 pos = calcPos();
|
||||||
|
auto batch = pctx->getBatch2D();
|
||||||
|
batch->texture(nullptr);
|
||||||
|
batch->lineWidth(1);
|
||||||
|
for (int i = index+1; i < index+dmwidth; i++) {
|
||||||
|
int j = i % dmwidth;
|
||||||
|
batch->line(
|
||||||
|
pos.x + i - index, pos.y + size.y - points[j],
|
||||||
|
pos.x + i - index, pos.y + size.y, 1.0f, 1.0f, 1.0f, 0.2f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
HudElement::HudElement(
|
HudElement::HudElement(
|
||||||
hud_element_mode mode,
|
hud_element_mode mode,
|
||||||
UiDocument* document,
|
UiDocument* document,
|
||||||
@ -74,6 +107,7 @@ HudElement::HudElement(
|
|||||||
void HudElement::update(bool pause, bool inventoryOpen, bool debugMode) {
|
void HudElement::update(bool pause, bool inventoryOpen, bool debugMode) {
|
||||||
if (debug && !debugMode) {
|
if (debug && !debugMode) {
|
||||||
node->setVisible(false);
|
node->setVisible(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case hud_element_mode::permanent:
|
case hud_element_mode::permanent:
|
||||||
@ -99,115 +133,6 @@ std::shared_ptr<gui::UINode> HudElement::getNode() const {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<UINode> Hud::createDebugPanel(Engine* engine) {
|
|
||||||
auto level = frontend->getLevel();
|
|
||||||
|
|
||||||
auto panel = std::make_shared<Panel>(glm::vec2(250, 200), glm::vec4(5.0f), 2.0f);
|
|
||||||
panel->listenInterval(0.5f, [this]() {
|
|
||||||
fpsString = std::to_wstring(fpsMax)+L" / "+std::to_wstring(fpsMin);
|
|
||||||
fpsMin = fps;
|
|
||||||
fpsMax = fps;
|
|
||||||
});
|
|
||||||
panel->setCoord(glm::vec2(10, 10));
|
|
||||||
panel->add(create_label([this](){ return L"fps: "+this->fpsString;}));
|
|
||||||
panel->add(create_label([](){
|
|
||||||
return L"meshes: " + std::to_wstring(Mesh::meshesCount);
|
|
||||||
}));
|
|
||||||
panel->add(create_label([=](){
|
|
||||||
auto& settings = engine->getSettings();
|
|
||||||
bool culling = settings.graphics.frustumCulling;
|
|
||||||
return L"frustum-culling: "+std::wstring(culling ? L"on" : L"off");
|
|
||||||
}));
|
|
||||||
panel->add(create_label([=]() {
|
|
||||||
return L"chunks: "+std::to_wstring(level->chunks->chunksCount)+
|
|
||||||
L" visible: "+std::to_wstring(level->chunks->visible);
|
|
||||||
}));
|
|
||||||
panel->add(create_label([=](){
|
|
||||||
auto* indices = level->content->getIndices();
|
|
||||||
auto def = indices->getBlockDef(player->selectedVoxel.id);
|
|
||||||
std::wstringstream stream;
|
|
||||||
stream << std::hex << player->selectedVoxel.states;
|
|
||||||
if (def) {
|
|
||||||
stream << L" (" << util::str2wstr_utf8(def->name) << L")";
|
|
||||||
}
|
|
||||||
return L"block: "+std::to_wstring(player->selectedVoxel.id)+
|
|
||||||
L" "+stream.str();
|
|
||||||
}));
|
|
||||||
panel->add(create_label([=](){
|
|
||||||
return L"seed: "+std::to_wstring(level->world->getSeed());
|
|
||||||
}));
|
|
||||||
|
|
||||||
for (int ax = 0; ax < 3; ax++) {
|
|
||||||
auto sub = std::make_shared<Container>(glm::vec2(), glm::vec2(250, 27));
|
|
||||||
|
|
||||||
std::wstring str = L"x: ";
|
|
||||||
str[0] += ax;
|
|
||||||
auto label = std::make_shared<Label>(str);
|
|
||||||
label->setMargin(glm::vec4(2, 3, 2, 3));
|
|
||||||
label->setSize(glm::vec2(20, 27));
|
|
||||||
sub->add(label);
|
|
||||||
sub->setColor(glm::vec4(0.0f));
|
|
||||||
|
|
||||||
// Coord input
|
|
||||||
auto box = std::make_shared<TextBox>(L"");
|
|
||||||
box->setTextSupplier([=]() {
|
|
||||||
Hitbox* hitbox = player->hitbox.get();
|
|
||||||
return util::to_wstring(hitbox->position[ax], 2);
|
|
||||||
});
|
|
||||||
box->setTextConsumer([=](std::wstring text) {
|
|
||||||
try {
|
|
||||||
glm::vec3 position = player->hitbox->position;
|
|
||||||
position[ax] = std::stoi(text);
|
|
||||||
player->teleport(position);
|
|
||||||
} catch (std::invalid_argument& _){
|
|
||||||
}
|
|
||||||
});
|
|
||||||
box->setOnEditStart([=](){
|
|
||||||
Hitbox* hitbox = player->hitbox.get();
|
|
||||||
box->setText(std::to_wstring(int(hitbox->position[ax])));
|
|
||||||
});
|
|
||||||
box->setSize(glm::vec2(230, 27));
|
|
||||||
|
|
||||||
sub->add(box, glm::vec2(20, 0));
|
|
||||||
panel->add(sub);
|
|
||||||
}
|
|
||||||
panel->add(create_label([=](){
|
|
||||||
int hour, minute, second;
|
|
||||||
timeutil::from_value(level->world->daytime, hour, minute, second);
|
|
||||||
|
|
||||||
std::wstring timeString =
|
|
||||||
util::lfill(std::to_wstring(hour), 2, L'0') + L":" +
|
|
||||||
util::lfill(std::to_wstring(minute), 2, L'0');
|
|
||||||
return L"time: "+timeString;
|
|
||||||
}));
|
|
||||||
{
|
|
||||||
auto bar = std::make_shared<TrackBar>(0.0f, 1.0f, 1.0f, 0.005f, 8);
|
|
||||||
bar->setSupplier([=]() {return level->world->daytime;});
|
|
||||||
bar->setConsumer([=](double val) {level->world->daytime = val;});
|
|
||||||
panel->add(bar);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto bar = std::make_shared<TrackBar>(0.0f, 1.0f, 0.0f, 0.005f, 8);
|
|
||||||
bar->setSupplier([=]() {return WorldRenderer::fog;});
|
|
||||||
bar->setConsumer([=](double val) {WorldRenderer::fog = val;});
|
|
||||||
panel->add(bar);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto checkbox = std::make_shared<FullCheckBox>(
|
|
||||||
L"Show Chunk Borders", glm::vec2(400, 24)
|
|
||||||
);
|
|
||||||
checkbox->setSupplier([=]() {
|
|
||||||
return engine->getSettings().debug.showChunkBorders;
|
|
||||||
});
|
|
||||||
checkbox->setConsumer([=](bool checked) {
|
|
||||||
engine->getSettings().debug.showChunkBorders = checked;
|
|
||||||
});
|
|
||||||
panel->add(checkbox);
|
|
||||||
}
|
|
||||||
panel->refresh();
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<InventoryView> Hud::createContentAccess() {
|
std::shared_ptr<InventoryView> Hud::createContentAccess() {
|
||||||
auto level = frontend->getLevel();
|
auto level = frontend->getLevel();
|
||||||
auto content = level->content;
|
auto content = level->content;
|
||||||
@ -258,8 +183,6 @@ Hud::Hud(Engine* engine, LevelFrontend* frontend, Player* player)
|
|||||||
frontend(frontend),
|
frontend(frontend),
|
||||||
player(player)
|
player(player)
|
||||||
{
|
{
|
||||||
auto menu = gui->getMenu();
|
|
||||||
|
|
||||||
interaction = std::make_unique<InventoryInteraction>();
|
interaction = std::make_unique<InventoryInteraction>();
|
||||||
grabbedItemView = std::make_shared<SlotView>(
|
grabbedItemView = std::make_shared<SlotView>(
|
||||||
SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr)
|
SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr)
|
||||||
@ -275,7 +198,7 @@ Hud::Hud(Engine* engine, LevelFrontend* frontend, Player* player)
|
|||||||
grabbedItemView->setZIndex(1);
|
grabbedItemView->setZIndex(1);
|
||||||
|
|
||||||
contentAccess = createContentAccess();
|
contentAccess = createContentAccess();
|
||||||
contentAccessPanel = std::make_shared<Panel>(
|
contentAccessPanel = std::make_shared<gui::Panel>(
|
||||||
contentAccess->getSize(), glm::vec4(0.0f), 0.0f
|
contentAccess->getSize(), glm::vec4(0.0f), 0.0f
|
||||||
);
|
);
|
||||||
contentAccessPanel->setColor(glm::vec4());
|
contentAccessPanel->setColor(glm::vec4());
|
||||||
@ -283,7 +206,7 @@ Hud::Hud(Engine* engine, LevelFrontend* frontend, Player* player)
|
|||||||
contentAccessPanel->setScrollable(true);
|
contentAccessPanel->setScrollable(true);
|
||||||
|
|
||||||
hotbarView = createHotbar();
|
hotbarView = createHotbar();
|
||||||
darkOverlay = std::make_unique<Panel>(glm::vec2(4000.0f));
|
darkOverlay = std::make_unique<gui::Panel>(glm::vec2(4000.0f));
|
||||||
darkOverlay->setColor(glm::vec4(0, 0, 0, 0.5f));
|
darkOverlay->setColor(glm::vec4(0, 0, 0, 0.5f));
|
||||||
darkOverlay->setZIndex(-1);
|
darkOverlay->setZIndex(-1);
|
||||||
darkOverlay->setVisible(false);
|
darkOverlay->setVisible(false);
|
||||||
@ -292,9 +215,7 @@ Hud::Hud(Engine* engine, LevelFrontend* frontend, Player* player)
|
|||||||
uicamera->perspective = false;
|
uicamera->perspective = false;
|
||||||
uicamera->flipped = true;
|
uicamera->flipped = true;
|
||||||
|
|
||||||
debugPanel = createDebugPanel(engine);
|
debugPanel = create_debug_panel(engine, frontend->getLevel(), player);
|
||||||
menu->reset();
|
|
||||||
|
|
||||||
debugPanel->setZIndex(2);
|
debugPanel->setZIndex(2);
|
||||||
|
|
||||||
gui->add(darkOverlay);
|
gui->add(darkOverlay);
|
||||||
@ -302,13 +223,17 @@ Hud::Hud(Engine* engine, LevelFrontend* frontend, Player* player)
|
|||||||
gui->add(debugPanel);
|
gui->add(debugPanel);
|
||||||
gui->add(contentAccessPanel);
|
gui->add(contentAccessPanel);
|
||||||
gui->add(grabbedItemView);
|
gui->add(grabbedItemView);
|
||||||
|
|
||||||
|
auto dgrapher = std::make_shared<DeltaGrapher>(350, 250, 2000);
|
||||||
|
dgrapher->setGravity(gui::Gravity::bottom_right);
|
||||||
|
add(HudElement(hud_element_mode::permanent, nullptr, dgrapher, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
Hud::~Hud() {
|
Hud::~Hud() {
|
||||||
// removing all controlled ui
|
// removing all controlled ui
|
||||||
gui->remove(grabbedItemView);
|
gui->remove(grabbedItemView);
|
||||||
for (auto& element : elements) {
|
for (auto& element : elements) {
|
||||||
remove(element);
|
onRemove(element);
|
||||||
}
|
}
|
||||||
gui->remove(hotbarView);
|
gui->remove(hotbarView);
|
||||||
gui->remove(darkOverlay);
|
gui->remove(darkOverlay);
|
||||||
@ -316,15 +241,7 @@ Hud::~Hud() {
|
|||||||
gui->remove(debugPanel);
|
gui->remove(debugPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hud::drawDebug(int fps){
|
/// @brief Remove all elements marked as removed
|
||||||
this->fps = fps;
|
|
||||||
fpsMin = min(fps, fpsMin);
|
|
||||||
fpsMax = max(fps, fpsMax);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all elements marked as removed
|
|
||||||
*/
|
|
||||||
void Hud::cleanup() {
|
void Hud::cleanup() {
|
||||||
auto it = std::remove_if(elements.begin(), elements.end(), [](const HudElement& e) {
|
auto it = std::remove_if(elements.begin(), elements.end(), [](const HudElement& e) {
|
||||||
return e.isRemoved();
|
return e.isRemoved();
|
||||||
@ -332,6 +249,48 @@ void Hud::cleanup() {
|
|||||||
elements.erase(it, elements.end());
|
elements.erase(it, elements.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Hud::processInput(bool visible) {
|
||||||
|
if (Events::jpressed(keycode::ESCAPE)) {
|
||||||
|
if (pause) {
|
||||||
|
setPause(false);
|
||||||
|
} else if (inventoryOpen) {
|
||||||
|
closeInventory();
|
||||||
|
} else {
|
||||||
|
setPause(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visible && Events::jactive(BIND_HUD_INVENTORY)) {
|
||||||
|
if (inventoryOpen) {
|
||||||
|
closeInventory();
|
||||||
|
} else {
|
||||||
|
openInventory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pause) {
|
||||||
|
if (!inventoryOpen && Events::scroll) {
|
||||||
|
int slot = player->getChosenSlot();
|
||||||
|
slot = (slot - Events::scroll) % 10;
|
||||||
|
if (slot < 0) {
|
||||||
|
slot += 10;
|
||||||
|
}
|
||||||
|
player->setChosenSlot(slot);
|
||||||
|
}
|
||||||
|
for (
|
||||||
|
int i = static_cast<int>(keycode::NUM_1);
|
||||||
|
i <= static_cast<int>(keycode::NUM_9);
|
||||||
|
i++
|
||||||
|
) {
|
||||||
|
if (Events::jpressed(i)) {
|
||||||
|
player->setChosenSlot(i - static_cast<int>(keycode::NUM_1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Events::jpressed(keycode::NUM_0)) {
|
||||||
|
player->setChosenSlot(9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Hud::update(bool visible) {
|
void Hud::update(bool visible) {
|
||||||
auto level = frontend->getLevel();
|
auto level = frontend->getLevel();
|
||||||
auto menu = gui->getMenu();
|
auto menu = gui->getMenu();
|
||||||
@ -344,31 +303,16 @@ void Hud::update(bool visible) {
|
|||||||
if (pause && menu->getCurrent().panel == nullptr) {
|
if (pause && menu->getCurrent().panel == nullptr) {
|
||||||
setPause(false);
|
setPause(false);
|
||||||
}
|
}
|
||||||
if (Events::jpressed(keycode::ESCAPE) && !gui->isFocusCaught()) {
|
|
||||||
if (pause) {
|
|
||||||
setPause(false);
|
|
||||||
} else if (inventoryOpen) {
|
|
||||||
closeInventory();
|
|
||||||
} else {
|
|
||||||
setPause(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (visible && !gui->isFocusCaught() && !pause) {
|
if (!gui->isFocusCaught()) {
|
||||||
if (Events::jactive(BIND_HUD_INVENTORY)) {
|
processInput(visible);
|
||||||
if (inventoryOpen) {
|
|
||||||
closeInventory();
|
|
||||||
} else {
|
|
||||||
openInventory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((pause || inventoryOpen) == Events::_cursor_locked) {
|
if ((pause || inventoryOpen) == Events::_cursor_locked) {
|
||||||
Events::toggleCursor();
|
Events::toggleCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockUI) {
|
if (blockUI) {
|
||||||
voxel* vox = level->chunks->get(currentblock.x, currentblock.y, currentblock.z);
|
voxel* vox = level->chunks->get(blockPos.x, blockPos.y, blockPos.z);
|
||||||
if (vox == nullptr || vox->id != currentblockid) {
|
if (vox == nullptr || vox->id != currentblockid) {
|
||||||
closeInventory();
|
closeInventory();
|
||||||
}
|
}
|
||||||
@ -384,58 +328,33 @@ void Hud::update(bool visible) {
|
|||||||
contentAccess->setMinSize(glm::vec2(1, Window::height));
|
contentAccess->setMinSize(glm::vec2(1, Window::height));
|
||||||
hotbarView->setVisible(visible);
|
hotbarView->setVisible(visible);
|
||||||
|
|
||||||
if (!gui->isFocusCaught() && !pause) {
|
|
||||||
for (int i = static_cast<int>(keycode::NUM_1); i <= static_cast<int>(keycode::NUM_9); i++) {
|
|
||||||
if (Events::jpressed(i)) {
|
|
||||||
player->setChosenSlot(i - static_cast<int>(keycode::NUM_1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Events::jpressed(keycode::NUM_0)) {
|
|
||||||
player->setChosenSlot(9);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!pause && !inventoryOpen && Events::scroll) {
|
|
||||||
int slot = player->getChosenSlot();
|
|
||||||
slot = (slot - Events::scroll) % 10;
|
|
||||||
if (slot < 0) {
|
|
||||||
slot += 10;
|
|
||||||
}
|
|
||||||
player->setChosenSlot(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (visible) {
|
if (visible) {
|
||||||
for (auto& element : elements) {
|
for (auto& element : elements) {
|
||||||
element.update(pause, inventoryOpen, player->debug);
|
element.update(pause, inventoryOpen, player->debug);
|
||||||
if (element.isRemoved()) {
|
if (element.isRemoved()) {
|
||||||
remove(element);
|
onRemove(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// @brief Show inventory on the screen and turn on inventory mode blocking movement
|
||||||
* Show inventory on the screen and turn on inventory mode blocking movement
|
|
||||||
*/
|
|
||||||
void Hud::openInventory() {
|
void Hud::openInventory() {
|
||||||
auto inventory = player->getInventory();
|
|
||||||
|
|
||||||
inventoryOpen = true;
|
inventoryOpen = true;
|
||||||
|
auto inventory = player->getInventory();
|
||||||
auto inventoryDocument = assets->getLayout("core:inventory");
|
auto inventoryDocument = assets->getLayout("core:inventory");
|
||||||
inventoryView = std::dynamic_pointer_cast<InventoryView>(inventoryDocument->getRoot());
|
inventoryView = std::dynamic_pointer_cast<InventoryView>(inventoryDocument->getRoot());
|
||||||
inventoryView->bind(inventory, frontend, interaction.get());
|
inventoryView->bind(inventory, frontend, interaction.get());
|
||||||
add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false));
|
add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void Hud::openInventory(
|
||||||
* Show player inventory + block UI
|
glm::ivec3 block,
|
||||||
* @param block world position of the open block
|
UiDocument* doc,
|
||||||
* @param doc block UI document (root element must be an InventoryView)
|
std::shared_ptr<Inventory> blockinv,
|
||||||
* @param blockinv block inventory.
|
bool playerInventory
|
||||||
* In case of nullptr a new virtual inventory will be created
|
) {
|
||||||
*/
|
|
||||||
void Hud::openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptr<Inventory> blockinv, bool playerInventory) {
|
|
||||||
if (isInventoryOpen()) {
|
if (isInventoryOpen()) {
|
||||||
closeInventory();
|
closeInventory();
|
||||||
}
|
}
|
||||||
@ -444,6 +363,7 @@ void Hud::openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptr<Inven
|
|||||||
if (blockUI == nullptr) {
|
if (blockUI == nullptr) {
|
||||||
throw std::runtime_error("block UI root element must be 'inventory'");
|
throw std::runtime_error("block UI root element must be 'inventory'");
|
||||||
}
|
}
|
||||||
|
secondUI = blockUI;
|
||||||
if (playerInventory) {
|
if (playerInventory) {
|
||||||
openInventory();
|
openInventory();
|
||||||
} else {
|
} else {
|
||||||
@ -454,15 +374,24 @@ void Hud::openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptr<Inven
|
|||||||
}
|
}
|
||||||
level->chunks->getChunkByVoxel(block.x, block.y, block.z)->setUnsaved(true);
|
level->chunks->getChunkByVoxel(block.x, block.y, block.z)->setUnsaved(true);
|
||||||
blockUI->bind(blockinv, frontend, interaction.get());
|
blockUI->bind(blockinv, frontend, interaction.get());
|
||||||
currentblock = block;
|
blockPos = block;
|
||||||
currentblockid = level->chunks->get(block.x, block.y, block.z)->id;
|
currentblockid = level->chunks->get(block.x, block.y, block.z)->id;
|
||||||
add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false));
|
add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void Hud::showOverlay(UiDocument* doc, bool playerInventory) {
|
||||||
* Add element as permanent overlay
|
if (isInventoryOpen()) {
|
||||||
* @param doc element layout document
|
closeInventory();
|
||||||
*/
|
}
|
||||||
|
secondUI = doc->getRoot();
|
||||||
|
if (playerInventory) {
|
||||||
|
openInventory();
|
||||||
|
} else {
|
||||||
|
inventoryOpen = true;
|
||||||
|
}
|
||||||
|
add(HudElement(hud_element_mode::inventory_bound, doc, secondUI, false));
|
||||||
|
}
|
||||||
|
|
||||||
void Hud::openPermanent(UiDocument* doc) {
|
void Hud::openPermanent(UiDocument* doc) {
|
||||||
auto root = doc->getRoot();
|
auto root = doc->getRoot();
|
||||||
remove(root);
|
remove(root);
|
||||||
@ -475,24 +404,13 @@ void Hud::openPermanent(UiDocument* doc) {
|
|||||||
add(HudElement(hud_element_mode::permanent, doc, doc->getRoot(), false));
|
add(HudElement(hud_element_mode::permanent, doc, doc->getRoot(), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide inventory and turn off inventory mode
|
|
||||||
*/
|
|
||||||
void Hud::closeInventory() {
|
void Hud::closeInventory() {
|
||||||
auto level = frontend->getLevel();
|
|
||||||
|
|
||||||
inventoryOpen = false;
|
inventoryOpen = false;
|
||||||
ItemStack& grabbed = interaction->getGrabbedItem();
|
ItemStack& grabbed = interaction->getGrabbedItem();
|
||||||
grabbed.clear();
|
grabbed.clear();
|
||||||
inventoryView = nullptr;
|
inventoryView = nullptr;
|
||||||
if (blockUI) {
|
|
||||||
auto blockinv = blockUI->getInventory();
|
|
||||||
// todo: do it automatically
|
|
||||||
if (blockinv->isVirtual()) {
|
|
||||||
level->inventories->remove(blockinv->getId());
|
|
||||||
}
|
|
||||||
blockUI = nullptr;
|
blockUI = nullptr;
|
||||||
}
|
secondUI = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hud::add(HudElement element) {
|
void Hud::add(HudElement element) {
|
||||||
@ -505,20 +423,20 @@ void Hud::add(HudElement element) {
|
|||||||
scripting::on_ui_open(
|
scripting::on_ui_open(
|
||||||
element.getDocument(),
|
element.getDocument(),
|
||||||
inventory.get(),
|
inventory.get(),
|
||||||
currentblock
|
blockPos
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
scripting::on_ui_open(
|
scripting::on_ui_open(
|
||||||
element.getDocument(),
|
element.getDocument(),
|
||||||
nullptr,
|
nullptr,
|
||||||
currentblock
|
blockPos
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elements.push_back(element);
|
elements.push_back(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hud::remove(HudElement& element) {
|
void Hud::onRemove(HudElement& element) {
|
||||||
auto document = element.getDocument();
|
auto document = element.getDocument();
|
||||||
if (document) {
|
if (document) {
|
||||||
Inventory* inventory = nullptr;
|
Inventory* inventory = nullptr;
|
||||||
@ -527,16 +445,18 @@ void Hud::remove(HudElement& element) {
|
|||||||
inventory = invview->getInventory().get();
|
inventory = invview->getInventory().get();
|
||||||
}
|
}
|
||||||
scripting::on_ui_close(document, inventory);
|
scripting::on_ui_close(document, inventory);
|
||||||
|
if (invview) {
|
||||||
|
invview->unbind();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gui->remove(element.getNode());
|
gui->remove(element.getNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: refactor this garbage
|
void Hud::remove(std::shared_ptr<gui::UINode> node) {
|
||||||
void Hud::remove(std::shared_ptr<UINode> node) {
|
|
||||||
for (auto& element : elements) {
|
for (auto& element : elements) {
|
||||||
if (element.getNode() == node) {
|
if (element.getNode() == node) {
|
||||||
element.setRemoved();
|
element.setRemoved();
|
||||||
remove(element);
|
onRemove(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanup();
|
cleanup();
|
||||||
@ -547,6 +467,8 @@ void Hud::draw(const GfxContext& ctx){
|
|||||||
const uint width = viewport.getWidth();
|
const uint width = viewport.getWidth();
|
||||||
const uint height = viewport.getHeight();
|
const uint height = viewport.getHeight();
|
||||||
|
|
||||||
|
updateElementsPosition(viewport);
|
||||||
|
|
||||||
uicamera->setFov(height);
|
uicamera->setFov(height);
|
||||||
|
|
||||||
auto batch = ctx.getBatch2D();
|
auto batch = ctx.getBatch2D();
|
||||||
@ -556,11 +478,8 @@ void Hud::draw(const GfxContext& ctx){
|
|||||||
uishader->use();
|
uishader->use();
|
||||||
uishader->uniformMatrix("u_projview", uicamera->getProjView());
|
uishader->uniformMatrix("u_projview", uicamera->getProjView());
|
||||||
|
|
||||||
hotbarView->setCoord(glm::vec2(width/2, height-65));
|
|
||||||
hotbarView->setSelected(player->getChosenSlot());
|
|
||||||
|
|
||||||
// Crosshair
|
// Crosshair
|
||||||
if (!pause && Events::_cursor_locked && !player->debug) {
|
if (!pause && !inventoryOpen && !player->debug) {
|
||||||
GfxContext chctx = ctx.sub();
|
GfxContext chctx = ctx.sub();
|
||||||
chctx.blendMode(blendmode::inversion);
|
chctx.blendMode(blendmode::inversion);
|
||||||
auto texture = assets->getTexture("gui/crosshair");
|
auto texture = assets->getTexture("gui/crosshair");
|
||||||
@ -573,55 +492,45 @@ void Hud::draw(const GfxContext& ctx){
|
|||||||
);
|
);
|
||||||
batch->flush();
|
batch->flush();
|
||||||
}
|
}
|
||||||
|
batch->flush();
|
||||||
|
}
|
||||||
|
|
||||||
// Delta-time visualizer
|
void Hud::updateElementsPosition(const Viewport& viewport) {
|
||||||
if (player->debug) {
|
const uint width = viewport.getWidth();
|
||||||
batch->texture(nullptr);
|
const uint height = viewport.getHeight();
|
||||||
const int dmwidth = 256;
|
|
||||||
const float dmscale = 4000.0f;
|
|
||||||
static float deltameter[dmwidth]{};
|
|
||||||
static int index=0;
|
|
||||||
index = index + 1 % dmwidth;
|
|
||||||
deltameter[index%dmwidth] = glm::min(0.2f, 1.f/fps)*dmscale;
|
|
||||||
batch->lineWidth(1);
|
|
||||||
for (int i = index+1; i < index+dmwidth; i++) {
|
|
||||||
int j = i % dmwidth;
|
|
||||||
batch->line(width-dmwidth+i-index, height-deltameter[j],
|
|
||||||
width-dmwidth+i-index, height, 1.0f, 1.0f, 1.0f, 0.2f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inventoryOpen) {
|
if (inventoryOpen) {
|
||||||
float caWidth = inventoryView ? contentAccess->getSize().x : 0.0f;
|
float caWidth = inventoryView ? contentAccess->getSize().x : 0.0f;
|
||||||
contentAccessPanel->setCoord(glm::vec2(width-caWidth, 0));
|
contentAccessPanel->setPos(glm::vec2(width-caWidth, 0));
|
||||||
|
|
||||||
glm::vec2 invSize = inventoryView ? inventoryView->getSize() : glm::vec2();
|
glm::vec2 invSize = inventoryView ? inventoryView->getSize() : glm::vec2();
|
||||||
if (blockUI == nullptr) {
|
if (secondUI == nullptr) {
|
||||||
if (inventoryView) {
|
if (inventoryView) {
|
||||||
inventoryView->setCoord(glm::vec2(
|
inventoryView->setPos(glm::vec2(
|
||||||
glm::min(width/2-invSize.x/2, width-caWidth-10-invSize.x),
|
glm::min(width/2-invSize.x/2, width-caWidth-10-invSize.x),
|
||||||
height/2-invSize.y/2
|
height/2-invSize.y/2
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
glm::vec2 blockInvSize = blockUI->getSize();
|
glm::vec2 secondUISize = secondUI->getSize();
|
||||||
float invwidth = glm::max(invSize.x, blockInvSize.x);
|
float invwidth = glm::max(invSize.x, secondUISize.x);
|
||||||
int interval = invSize.y > 0.0 ? 5 : 0;
|
int interval = invSize.y > 0.0 ? 5 : 0;
|
||||||
float totalHeight = invSize.y + blockInvSize.y + interval;
|
float totalHeight = invSize.y + secondUISize.y + interval;
|
||||||
if (inventoryView) {
|
if (inventoryView) {
|
||||||
inventoryView->setCoord(glm::vec2(
|
inventoryView->setPos(glm::vec2(
|
||||||
glm::min(width/2-invwidth/2, width-caWidth-10-invwidth),
|
glm::min(width/2-invwidth/2, width-caWidth-10-invwidth),
|
||||||
height/2+totalHeight/2-invSize.y
|
height/2+totalHeight/2-invSize.y
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
blockUI->setCoord(glm::vec2(
|
secondUI->setPos(glm::vec2(
|
||||||
glm::min(width/2-invwidth/2, width-caWidth-10-invwidth),
|
glm::min(width/2-invwidth/2, width-caWidth-10-invwidth),
|
||||||
height/2-totalHeight/2
|
height/2-totalHeight/2
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
grabbedItemView->setCoord(glm::vec2(Events::cursor));
|
grabbedItemView->setPos(glm::vec2(Events::cursor));
|
||||||
batch->flush();
|
hotbarView->setPos(glm::vec2(width/2, height-65));
|
||||||
|
hotbarView->setSelected(player->getChosenSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hud::isInventoryOpen() const {
|
bool Hud::isInventoryOpen() const {
|
||||||
|
|||||||
@ -9,11 +9,9 @@
|
|||||||
#include "../graphics/GfxContext.h"
|
#include "../graphics/GfxContext.h"
|
||||||
|
|
||||||
class Camera;
|
class Camera;
|
||||||
class Level;
|
|
||||||
class Block;
|
class Block;
|
||||||
class Assets;
|
class Assets;
|
||||||
class Player;
|
class Player;
|
||||||
class Level;
|
|
||||||
class Engine;
|
class Engine;
|
||||||
class SlotView;
|
class SlotView;
|
||||||
class Inventory;
|
class Inventory;
|
||||||
@ -68,36 +66,49 @@ class Hud {
|
|||||||
Engine* engine;
|
Engine* engine;
|
||||||
Assets* assets;
|
Assets* assets;
|
||||||
std::unique_ptr<Camera> uicamera;
|
std::unique_ptr<Camera> uicamera;
|
||||||
|
|
||||||
int fps = 60;
|
|
||||||
int fpsMin = 60;
|
|
||||||
int fpsMax = 60;
|
|
||||||
std::wstring fpsString;
|
|
||||||
bool inventoryOpen = false;
|
|
||||||
bool pause = false;
|
|
||||||
|
|
||||||
std::shared_ptr<gui::Container> contentAccessPanel;
|
|
||||||
std::shared_ptr<InventoryView> contentAccess;
|
|
||||||
std::shared_ptr<InventoryView> hotbarView;
|
|
||||||
std::shared_ptr<gui::UINode> debugPanel;
|
|
||||||
std::shared_ptr<gui::Panel> darkOverlay;
|
|
||||||
std::unique_ptr<InventoryInteraction> interaction;
|
|
||||||
std::shared_ptr<SlotView> grabbedItemView;
|
|
||||||
gui::GUI* gui;
|
gui::GUI* gui;
|
||||||
LevelFrontend* frontend;
|
LevelFrontend* frontend;
|
||||||
Player* player;
|
Player* player;
|
||||||
|
|
||||||
|
/// @brief Is any overlay/inventory open
|
||||||
|
bool inventoryOpen = false;
|
||||||
|
/// @brief Is pause mode on
|
||||||
|
bool pause = false;
|
||||||
|
|
||||||
|
/// @brief Content access panel scroll container
|
||||||
|
std::shared_ptr<gui::Container> contentAccessPanel;
|
||||||
|
/// @brief Content access panel itself
|
||||||
|
std::shared_ptr<InventoryView> contentAccess;
|
||||||
|
/// @brief Player inventory hotbar
|
||||||
|
std::shared_ptr<InventoryView> hotbarView;
|
||||||
|
/// @brief Debug info and control panel (F3 key)
|
||||||
|
std::shared_ptr<gui::UINode> debugPanel;
|
||||||
|
/// @brief Overlay used in pause mode
|
||||||
|
std::shared_ptr<gui::Panel> darkOverlay;
|
||||||
|
/// @brief Inventories interaction agent (grabbed item and other info)
|
||||||
|
std::unique_ptr<InventoryInteraction> interaction;
|
||||||
|
/// @brief Grabbed item visual element
|
||||||
|
std::shared_ptr<SlotView> grabbedItemView;
|
||||||
|
/// @brief List of all controlled hud elements
|
||||||
std::vector<HudElement> elements;
|
std::vector<HudElement> elements;
|
||||||
|
|
||||||
|
/// @brief Player inventory view
|
||||||
std::shared_ptr<InventoryView> inventoryView = nullptr;
|
std::shared_ptr<InventoryView> inventoryView = nullptr;
|
||||||
|
/// @brief Block inventory view
|
||||||
std::shared_ptr<InventoryView> blockUI = nullptr;
|
std::shared_ptr<InventoryView> blockUI = nullptr;
|
||||||
glm::ivec3 currentblock {};
|
/// @brief Position of the block open
|
||||||
|
glm::ivec3 blockPos {};
|
||||||
|
/// @brief Id of the block open (used to detect block destruction or replacement)
|
||||||
blockid_t currentblockid = 0;
|
blockid_t currentblockid = 0;
|
||||||
|
|
||||||
std::shared_ptr<gui::UINode> createDebugPanel(Engine* engine);
|
/// @brief UI element will be dynamicly positioned near to inventory or in screen center
|
||||||
|
std::shared_ptr<gui::UINode> secondUI = nullptr;
|
||||||
|
|
||||||
std::shared_ptr<InventoryView> createContentAccess();
|
std::shared_ptr<InventoryView> createContentAccess();
|
||||||
std::shared_ptr<InventoryView> createHotbar();
|
std::shared_ptr<InventoryView> createHotbar();
|
||||||
|
|
||||||
|
void processInput(bool visible);
|
||||||
|
void updateElementsPosition(const Viewport& viewport);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
public:
|
public:
|
||||||
Hud(Engine* engine, LevelFrontend* frontend, Player* player);
|
Hud(Engine* engine, LevelFrontend* frontend, Player* player);
|
||||||
@ -105,22 +116,43 @@ public:
|
|||||||
|
|
||||||
void update(bool hudVisible);
|
void update(bool hudVisible);
|
||||||
void draw(const GfxContext& context);
|
void draw(const GfxContext& context);
|
||||||
void drawDebug(int fps);
|
|
||||||
|
|
||||||
|
/// @brief Check if inventory mode on
|
||||||
bool isInventoryOpen() const;
|
bool isInventoryOpen() const;
|
||||||
|
|
||||||
|
/// @brief Check if pause mode on
|
||||||
bool isPause() const;
|
bool isPause() const;
|
||||||
|
|
||||||
|
/// @brief Enable/disable pause mode
|
||||||
void setPause(bool pause);
|
void setPause(bool pause);
|
||||||
|
|
||||||
|
/// @brief Show player inventory in inventory-mode
|
||||||
void openInventory();
|
void openInventory();
|
||||||
|
|
||||||
|
/// @brief Show block inventory in inventory-mode
|
||||||
|
/// @param block block position
|
||||||
|
/// @param doc block ui layout
|
||||||
|
/// @param blockInv block inventory
|
||||||
|
/// @param playerInventory show player inventory too
|
||||||
void openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptr<Inventory> blockInv, bool playerInventory);
|
void openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptr<Inventory> blockInv, bool playerInventory);
|
||||||
|
|
||||||
|
/// @brief Show element in inventory-mode
|
||||||
|
/// @param doc element layout
|
||||||
|
/// @param playerInventory show player inventory too
|
||||||
|
void showOverlay(UiDocument* doc, bool playerInventory);
|
||||||
|
|
||||||
|
/// @brief Close all open inventories and overlay
|
||||||
void closeInventory();
|
void closeInventory();
|
||||||
|
|
||||||
|
/// @brief Add element will be visible until removed
|
||||||
|
/// @param doc element layout
|
||||||
void openPermanent(UiDocument* doc);
|
void openPermanent(UiDocument* doc);
|
||||||
|
|
||||||
void add(HudElement element);
|
void add(HudElement element);
|
||||||
void remove(HudElement& element);
|
void onRemove(HudElement& element);
|
||||||
void remove(std::shared_ptr<gui::UINode> node);
|
void remove(std::shared_ptr<gui::UINode> node);
|
||||||
|
|
||||||
Player* getPlayer() const;
|
Player* getPlayer() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SRC_HUD_H_ */
|
#endif // SRC_HUD_H_
|
||||||
|
|||||||
@ -92,6 +92,8 @@ static bool backlight;
|
|||||||
LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) {
|
LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) {
|
||||||
auto& settings = engine->getSettings();
|
auto& settings = engine->getSettings();
|
||||||
auto assets = engine->getAssets();
|
auto assets = engine->getAssets();
|
||||||
|
auto menu = engine->getGUI()->getMenu();
|
||||||
|
menu->reset();
|
||||||
|
|
||||||
controller = std::make_unique<LevelController>(settings, level);
|
controller = std::make_unique<LevelController>(settings, level);
|
||||||
frontend = std::make_unique<LevelFrontend>(level, assets);
|
frontend = std::make_unique<LevelFrontend>(level, assets);
|
||||||
@ -186,8 +188,5 @@ void LevelScreen::draw(float delta) {
|
|||||||
|
|
||||||
if (hudVisible) {
|
if (hudVisible) {
|
||||||
hud->draw(ctx);
|
hud->draw(ctx);
|
||||||
if (controller->getPlayer()->debug) {
|
|
||||||
hud->drawDebug(1 / delta);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,12 +19,11 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), color(1.0f){
|
|||||||
ubyte pixels[] = {
|
ubyte pixels[] = {
|
||||||
0xFF, 0xFF, 0xFF, 0xFF
|
0xFF, 0xFF, 0xFF, 0xFF
|
||||||
};
|
};
|
||||||
blank = new Texture(pixels, 1, 1, GL_RGBA);
|
blank = std::make_unique<Texture>(pixels, 1, 1, GL_RGBA);
|
||||||
_texture = nullptr;
|
_texture = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Batch2D::~Batch2D(){
|
Batch2D::~Batch2D(){
|
||||||
delete blank;
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,10 +15,9 @@ class Batch2D {
|
|||||||
float* buffer;
|
float* buffer;
|
||||||
size_t capacity;
|
size_t capacity;
|
||||||
std::unique_ptr<Mesh> mesh;
|
std::unique_ptr<Mesh> mesh;
|
||||||
|
std::unique_ptr<Texture> blank;
|
||||||
size_t index;
|
size_t index;
|
||||||
glm::vec4 color;
|
glm::vec4 color;
|
||||||
|
|
||||||
Texture* blank;
|
|
||||||
Texture* _texture;
|
Texture* _texture;
|
||||||
|
|
||||||
void vertex(
|
void vertex(
|
||||||
|
|||||||
@ -171,7 +171,7 @@ static int l_gui_getattr(lua_State* L) {
|
|||||||
if (attr == "color") {
|
if (attr == "color") {
|
||||||
return lua::pushcolor_arr(L, node->getColor());
|
return lua::pushcolor_arr(L, node->getColor());
|
||||||
} else if (attr == "pos") {
|
} else if (attr == "pos") {
|
||||||
return lua::pushvec2_arr(L, node->getCoord());
|
return lua::pushvec2_arr(L, node->getPos());
|
||||||
} else if (attr == "size") {
|
} else if (attr == "size") {
|
||||||
return lua::pushvec2_arr(L, node->getSize());
|
return lua::pushvec2_arr(L, node->getSize());
|
||||||
} else if (attr == "hoverColor") {
|
} else if (attr == "hoverColor") {
|
||||||
@ -210,7 +210,7 @@ static int l_gui_setattr(lua_State* L) {
|
|||||||
|
|
||||||
auto node = getDocumentNode(L, docname, element);
|
auto node = getDocumentNode(L, docname, element);
|
||||||
if (attr == "pos") {
|
if (attr == "pos") {
|
||||||
node->setCoord(lua::tovec2(L, 4));
|
node->setPos(lua::tovec2(L, 4));
|
||||||
} else if (attr == "size") {
|
} else if (attr == "size") {
|
||||||
node->setSize(lua::tovec2(L, 4));
|
node->setSize(lua::tovec2(L, 4));
|
||||||
} else if (attr == "color") {
|
} else if (attr == "color") {
|
||||||
|
|||||||
@ -65,6 +65,19 @@ static int l_hud_open_block(lua_State* L) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_hud_show_overlay(lua_State* L) {
|
||||||
|
const char* name = lua_tostring(L, 1);
|
||||||
|
bool playerInventory = lua_toboolean(L, 2);
|
||||||
|
|
||||||
|
auto assets = scripting::engine->getAssets();
|
||||||
|
auto layout = assets->getLayout(name);
|
||||||
|
if (layout == nullptr) {
|
||||||
|
luaL_error(L, "there is no ui layout '%s'", name);
|
||||||
|
}
|
||||||
|
scripting::hud->showOverlay(layout, playerInventory);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static UiDocument* require_layout(lua_State* L, const char* name) {
|
static UiDocument* require_layout(lua_State* L, const char* name) {
|
||||||
auto assets = scripting::engine->getAssets();
|
auto assets = scripting::engine->getAssets();
|
||||||
auto layout = assets->getLayout(name);
|
auto layout = assets->getLayout(name);
|
||||||
@ -91,6 +104,7 @@ const luaL_Reg hudlib [] = {
|
|||||||
{"close_inventory", lua_wrap_errors<l_hud_close_inventory>},
|
{"close_inventory", lua_wrap_errors<l_hud_close_inventory>},
|
||||||
{"open_block", lua_wrap_errors<l_hud_open_block>},
|
{"open_block", lua_wrap_errors<l_hud_open_block>},
|
||||||
{"open_permanent", lua_wrap_errors<l_hud_open_permanent>},
|
{"open_permanent", lua_wrap_errors<l_hud_open_permanent>},
|
||||||
|
{"show_overlay", lua_wrap_errors<l_hud_show_overlay>},
|
||||||
{"close", lua_wrap_errors<l_hud_close>},
|
{"close", lua_wrap_errors<l_hud_close>},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user