misc hud-related updates

This commit is contained in:
MihailRis
2024-02-15 14:43:03 +03:00
parent 1f3d1e2640
commit 11bb9e5926
23 changed files with 400 additions and 165 deletions
+11 -2
View File
@@ -44,6 +44,15 @@ InventoryBuilder::InventoryBuilder() {
view = std::make_shared<InventoryView>();
}
/** Add slots grid to inventory view
* @param cols grid columns
* @param count total number of grid slots
* @param coord position of the first slot of the grid
* @param padding additional space around the grid
* @param addpanel automatically create panel behind the grid
* with size including padding
* @param slotLayout slot settings (index and position are ignored)
*/
void InventoryBuilder::addGrid(
int cols, int count,
glm::vec2 coord,
@@ -70,7 +79,7 @@ void InventoryBuilder::addGrid(
if (addpanel) {
auto panel = std::make_shared<gui::Container>(coord, glm::vec2(width, height));
view->setColor(glm::vec4(0, 0, 0, 0.5f));
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f));
view->add(panel);
}
@@ -416,7 +425,7 @@ static void readSlotsGrid(InventoryView* view, gui::UiXmlReader& reader, xml::xm
slotLayout.index = startIndex + idx;
slotLayout.position += glm::vec2(
padding + col * (slotSize + interval),
padding + row * (slotSize + interval)
padding + (rows-row-1) * (slotSize + interval)
);
auto slot = view->addSlot(slotLayout);
view->add(slot, slotLayout.position);
+1
View File
@@ -69,6 +69,7 @@ std::unique_ptr<UiDocument> UiDocument::read(AssetsLoader& loader, int penv, std
auto view = reader.readXML(
file.u8string(), xmldoc->getRoot()
);
view->setId("root");
uidocscript script {};
auto scriptFile = fs::path(file.u8string()+".lua");
if (fs::is_regular_file(scriptFile)) {
+4
View File
@@ -170,3 +170,7 @@ void GUI::setFocus(std::shared_ptr<UINode> node) {
focus->focus(this);
}
}
std::shared_ptr<Container> GUI::getContainer() const {
return container;
}
+2
View File
@@ -76,6 +76,8 @@ namespace gui {
std::shared_ptr<UINode> get(std::string name);
void remove(std::string name);
void setFocus(std::shared_ptr<UINode> node);
std::shared_ptr<Container> getContainer() const;
};
}
+26 -1
View File
@@ -119,7 +119,18 @@ glm::vec2 UINode::getSize() const {
}
void UINode::setSize(glm::vec2 size) {
this->size = size;
this->size = glm::vec2(
glm::max(minSize.x, size.x), glm::max(minSize.y, size.y)
);
}
glm::vec2 UINode::getMinSize() const {
return minSize;
}
void UINode::setMinSize(glm::vec2 minSize) {
this->minSize = minSize;
setSize(getSize());
}
void UINode::setColor(glm::vec4 color) {
@@ -158,6 +169,14 @@ int UINode::getZIndex() const {
void UINode::lock() {
}
vec2supplier UINode::getPositionFunc() const {
return positionfunc;
}
void UINode::setPositionFunc(vec2supplier func) {
positionfunc = func;
}
void UINode::setId(const std::string& id) {
this->id = id;
}
@@ -165,3 +184,9 @@ void UINode::setId(const std::string& id) {
const std::string& UINode::getId() const {
return id;
}
void UINode::reposition() {
if (positionfunc) {
setCoord(positionfunc());
}
}
+12 -1
View File
@@ -6,6 +6,7 @@
#include <memory>
#include <string>
#include <functional>
#include "../../delegates.h"
class GfxContext;
class Assets;
@@ -26,6 +27,7 @@ namespace gui {
protected:
glm::vec2 coord;
glm::vec2 size;
glm::vec2 minSize {1.0f};
glm::vec4 color {1.0f};
glm::vec4 hoverColor {1.0f};
glm::vec4 margin {1.0f};
@@ -38,6 +40,7 @@ namespace gui {
int zindex = 0;
Align align = Align::left;
UINode* parent = nullptr;
vec2supplier positionfunc = nullptr;
UINode(glm::vec2 coord, glm::vec2 size);
public:
virtual ~UINode();
@@ -112,14 +115,22 @@ namespace gui {
/* Calculate screen position of the element */
virtual glm::vec2 calcCoord() const;
virtual void setCoord(glm::vec2 coord);
glm::vec2 getCoord() const;
virtual glm::vec2 getCoord() const;
virtual glm::vec2 getSize() const;
virtual void setSize(glm::vec2 size);
virtual glm::vec2 getMinSize() const;
virtual void setMinSize(glm::vec2 size);
virtual void refresh() {};
virtual void lock();
virtual vec2supplier getPositionFunc() const;
virtual void setPositionFunc(vec2supplier);
void setId(const std::string& id);
const std::string& getId() const;
/* Fetch coord from positionfunc if assigned */
void reposition();
};
}
+15 -3
View File
@@ -6,6 +6,7 @@
#include "../../assets/Assets.h"
#include "../../graphics/Batch2D.h"
#include "../../graphics/Font.h"
#include "../../graphics/Texture.h"
#include "../../graphics/GfxContext.h"
#include "../../util/stringutil.h"
#include "GUI.h"
@@ -64,9 +65,8 @@ void Label::draw(const GfxContext* pctx, Assets* assets) {
font->draw(batch, text, coord.x, coord.y);
}
Label* Label::textSupplier(wstringsupplier supplier) {
void Label::textSupplier(wstringsupplier supplier) {
this->supplier = supplier;
return this;
}
// ================================= Image ====================================
@@ -78,12 +78,24 @@ void Image::draw(const GfxContext* pctx, Assets* assets) {
glm::vec2 coord = calcCoord();
glm::vec4 color = getColor();
auto batch = pctx->getBatch2D();
batch->texture(assets->getTexture(texture));
auto texture = assets->getTexture(this->texture);
if (texture && autoresize) {
setSize(glm::vec2(texture->width, texture->height));
}
batch->texture(texture);
batch->color = color;
batch->rect(coord.x, coord.y, size.x, size.y,
0, 0, 0, UVRegion(), false, true, color);
}
void Image::setAutoResize(bool flag) {
autoresize = flag;
}
bool Image::isAutoResize() const {
return autoresize;
}
// ================================= Button ===================================
Button::Button(std::shared_ptr<UINode> content, glm::vec4 padding)
: Panel(glm::vec2(), padding, 0) {
+5 -1
View File
@@ -31,16 +31,20 @@ namespace gui {
virtual void draw(const GfxContext* pctx, Assets* assets) override;
virtual Label* textSupplier(wstringsupplier supplier);
virtual void textSupplier(wstringsupplier supplier);
};
class Image : public UINode {
protected:
std::string texture;
bool autoresize = false;
public:
Image(std::string texture, glm::vec2 size=glm::vec2(32,32));
virtual void draw(const GfxContext* pctx, Assets* assets) override;
virtual void setAutoResize(bool flag);
virtual bool isAutoResize() const;
};
class Button : public Panel {
+15 -7
View File
@@ -21,7 +21,7 @@ static Align align_from_string(const std::string& str, Align def) {
}
/* Read basic UINode properties */
static void _readUINode(xml::xmlelement element, UINode& node) {
static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) {
if (element->has("id")) {
node.setId(element->attr("id").getText());
}
@@ -40,13 +40,21 @@ static void _readUINode(xml::xmlelement element, UINode& node) {
if (element->has("z-index")) {
node.setZIndex(element->attr("z-index").asInt());
}
if (element->has("position-func")) {
auto supplier = scripting::create_vec2_supplier(
reader.getEnvironment().getId(),
element->attr("position-func").getText(),
reader.getFilename()+".lua"
);
node.setPositionFunc(supplier);
}
std::string alignName = element->attr("align", "").getText();
node.setAlign(align_from_string(alignName, node.getAlign()));
}
static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container) {
_readUINode(element, container);
_readUINode(reader, element, container);
if (element->has("scrollable")) {
container.setScrollable(element->attr("scrollable").asBool());
@@ -66,11 +74,11 @@ void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, Conta
}
void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) {
_readUINode(element, node);
_readUINode(reader, element, node);
}
static void _readPanel(UiXmlReader& reader, xml::xmlelement element, Panel& panel) {
_readUINode(element, panel);
_readUINode(reader, element, panel);
if (element->has("padding")) {
glm::vec4 padding = element->attr("padding").asVec4();
@@ -114,7 +122,7 @@ static std::wstring readAndProcessInnerText(xml::xmlelement element) {
static std::shared_ptr<UINode> readLabel(UiXmlReader& reader, xml::xmlelement element) {
std::wstring text = readAndProcessInnerText(element);
auto label = std::make_shared<Label>(text);
_readUINode(element, *label);
_readUINode(reader, element, *label);
return label;
}
@@ -173,7 +181,7 @@ static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, xml::xmlelement
static std::shared_ptr<UINode> readImage(UiXmlReader& reader, xml::xmlelement element) {
std::string src = element->attr("src", "").getText();
auto image = std::make_shared<Image>(src);
_readUINode(element, *image);
_readUINode(reader, element, *image);
reader.getAssetsLoader().add(ASSET_TEXTURE, "textures/"+src+".png", src, nullptr);
return image;
}
@@ -185,7 +193,7 @@ static std::shared_ptr<UINode> readTrackBar(UiXmlReader& reader, xml::xmlelement
float step = element->attr("step", "1.0").asFloat();
int trackWidth = element->attr("track-width", "1.0").asInt();
auto bar = std::make_shared<TrackBar>(min, max, def, step, trackWidth);
_readUINode(element, *bar);
_readUINode(reader, element, *bar);
if (element->has("consumer")) {
auto consumer = scripting::create_number_consumer(
reader.getEnvironment().getId(),
+8
View File
@@ -115,6 +115,7 @@ void Container::addBack(std::shared_ptr<UINode> node) {
void Container::add(std::shared_ptr<UINode> node) {
nodes.push_back(node);
node->setParent(this);
node->reposition();
refresh();
}
@@ -138,8 +139,15 @@ void Container::listenInterval(float interval, ontimeout callback, int repeat) {
}
void Container::setSize(glm::vec2 size) {
if (size == getSize()) {
refresh();
return;
}
UINode::setSize(size);
refresh();
for (auto& node : nodes) {
node->reposition();
}
}
void Container::refresh() {
+94 -19
View File
@@ -20,6 +20,7 @@
#include "../graphics/Font.h"
#include "../graphics/Atlas.h"
#include "../graphics/Mesh.h"
#include "../graphics/Texture.h"
#include "../window/Camera.h"
#include "../window/Window.h"
#include "../window/Events.h"
@@ -57,6 +58,42 @@ static std::shared_ptr<Label> create_label(wstringsupplier supplier) {
return label;
}
HudElement::HudElement(
hud_element_mode mode,
UiDocument* document,
std::shared_ptr<gui::UINode> node,
bool debug
) : mode(mode), document(document), node(node), debug(debug) {
}
void HudElement::update(bool pause, bool inventoryOpen, bool debugMode) {
if (debug && !debugMode) {
node->setVisible(false);
}
switch (mode) {
case hud_element_mode::permanent:
node->setVisible(true);
break;
case hud_element_mode::ingame:
node->setVisible(!pause && !inventoryOpen);
break;
case hud_element_mode::inventory_any:
node->setVisible(inventoryOpen);
break;
case hud_element_mode::inventory_bound:
removed = !inventoryOpen;
break;
}
}
UiDocument* HudElement::getDocument() const {
return document;
}
std::shared_ptr<gui::UINode> HudElement::getNode() const {
return node;
}
std::shared_ptr<UINode> HudRenderer::createDebugPanel(Engine* engine) {
auto level = frontend->getLevel();
@@ -96,7 +133,7 @@ std::shared_ptr<UINode> HudRenderer::createDebugPanel(Engine* engine) {
return L"seed: "+std::to_wstring(level->world->getSeed());
}));
for (int ax = 0; ax < 3; ax++){
for (int ax = 0; ax < 3; ax++) {
auto sub = std::make_shared<Container>(glm::vec2(), glm::vec2(250, 27));
std::wstring str = L"x: ";
@@ -193,6 +230,7 @@ std::shared_ptr<InventoryView> HudRenderer::createContentAccess() {
builder.addGrid(8, itemsCount-1, glm::vec2(), 8, true, slotLayout);
auto view = builder.build();
view->bind(accessInventory, frontend, interaction.get());
view->setMargin(glm::vec4());
return view;
}
@@ -265,8 +303,8 @@ HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend)
HudRenderer::~HudRenderer() {
// removing all controlled ui
gui->remove(grabbedItemView);
if (inventoryView) {
gui->remove(inventoryView);
for (auto& element : elements) {
remove(element);
}
gui->remove(hotbarView);
gui->remove(darkOverlay);
@@ -318,7 +356,8 @@ void HudRenderer::update(bool visible) {
glm::vec2 invSize = contentAccessPanel->getSize();
contentAccessPanel->setVisible(inventoryOpen);
contentAccessPanel->setSize(glm::vec2(invSize.x, Window::height));
hotbarView->setVisible(visible);
contentAccess->setMinSize(glm::vec2(1, Window::height));
// hotbarView->setVisible(visible && !inventoryOpen);
for (int i = keycode::NUM_1; i <= keycode::NUM_9; i++) {
if (Events::jpressed(i)) {
@@ -336,6 +375,17 @@ void HudRenderer::update(bool visible) {
}
player->setChosenSlot(slot);
}
for (auto& element : elements) {
element.update(pause, inventoryOpen, player->debug);
if (element.isRemoved()) {
remove(element);
}
}
auto it = std::remove_if(elements.begin(), elements.end(), [](const HudElement& e) {
return e.isRemoved();
});
elements.erase(it, elements.end());
}
/**
@@ -348,25 +398,48 @@ void HudRenderer::openInventory() {
inventoryOpen = true;
inventoryDocument = assets->getLayout("core:inventory");
auto inventoryDocument = assets->getLayout("core:inventory");
inventoryView = std::dynamic_pointer_cast<InventoryView>(inventoryDocument->getRoot());
inventoryView->bind(inventory, frontend, interaction.get());
scripting::on_ui_open(inventoryDocument, inventory.get());
gui->add(inventoryView);
add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false));
}
/**
* Hide inventory and turn off inventory mode
*/
void HudRenderer::closeInventory() {
scripting::on_ui_close(inventoryDocument, inventoryView->getInventory().get());
inventoryOpen = false;
ItemStack& grabbed = interaction->getGrabbedItem();
grabbed.clear();
gui->remove(inventoryView);
inventoryView = nullptr;
inventoryDocument = nullptr;
}
void HudRenderer::add(HudElement element) {
gui->add(element.getNode());
auto invview = std::dynamic_pointer_cast<InventoryView>(element.getNode());
auto document = element.getDocument();
if (document) {
if (invview) {
auto inventory = invview->getInventory();
scripting::on_ui_open(element.getDocument(), inventory.get());
} else {
scripting::on_ui_open(element.getDocument(), nullptr);
}
}
elements.push_back(element);
}
void HudRenderer::remove(HudElement& element) {
auto document = element.getDocument();
if (document) {
Inventory* inventory = nullptr;
auto invview = std::dynamic_pointer_cast<InventoryView>(element.getNode());
if (invview) {
inventory = invview->getInventory().get();
}
scripting::on_ui_close(document, inventory);
}
gui->remove(element.getNode());
}
void HudRenderer::draw(const GfxContext& ctx){
@@ -393,11 +466,13 @@ void HudRenderer::draw(const GfxContext& ctx){
if (!pause && Events::_cursor_locked && !level->player->debug) {
GfxContext chctx = ctx.sub();
chctx.blendMode(blendmode::inversion);
batch->texture(assets->getTexture("gui/crosshair"));
int chsize = 16;
auto texture = assets->getTexture("gui/crosshair");
batch->texture(texture);
int chsizex = texture != nullptr ? texture->width : 16;
int chsizey = texture != nullptr ? texture->height : 16;
batch->rect(
(width-chsize)/2, (height-chsize)/2,
chsize, chsize, 0,0, 1,1, 1,1,1,1
(width-chsizex)/2, (height-chsizey)/2,
chsizex, chsizey, 0,0, 1,1, 1,1,1,1
);
batch->render();
}
@@ -424,10 +499,10 @@ void HudRenderer::draw(const GfxContext& ctx){
contentAccessPanel->setCoord(glm::vec2(width-caWidth, 0));
glm::vec2 invSize = inventoryView->getSize();
inventoryView->setCoord(glm::vec2(
glm::min(width/2-invSize.x/2, width-caWidth-10-invSize.x),
height/2-invSize.y/2
));
//inventoryView->setCoord(glm::vec2(
// glm::min(width/2-invSize.x/2, width-caWidth-10-invSize.x),
// height/2-invSize.y/2
//));
}
grabbedItemView->setCoord(glm::vec2(Events::cursor));
batch->render();
+38 -2
View File
@@ -25,8 +25,40 @@ namespace gui {
class GUI;
class UINode;
class Panel;
class Container;
}
enum class hud_element_mode {
// element is hidden if menu or inventory open
ingame,
// element is visible if hud is visible
permanent,
// element is visible in inventory mode
inventory_any,
// element will be removed on inventory close
inventory_bound
};
class HudElement {
hud_element_mode mode;
UiDocument* document;
std::shared_ptr<gui::UINode> node;
bool debug;
bool removed = false;
public:
HudElement(hud_element_mode mode, UiDocument* document, std::shared_ptr<gui::UINode> node, bool debug);
void update(bool pause, bool inventoryOpen, bool debug);
UiDocument* getDocument() const;
std::shared_ptr<gui::UINode> getNode() const;
bool isRemoved() const {
return removed;
}
};
class HudRenderer {
Assets* assets;
std::unique_ptr<Camera> uicamera;
@@ -38,7 +70,7 @@ class HudRenderer {
bool inventoryOpen = false;
bool pause = false;
std::shared_ptr<gui::Panel> contentAccessPanel;
std::shared_ptr<gui::Container> contentAccessPanel;
std::shared_ptr<InventoryView> contentAccess;
std::shared_ptr<InventoryView> hotbarView;
std::shared_ptr<gui::UINode> debugPanel;
@@ -48,8 +80,9 @@ class HudRenderer {
gui::GUI* gui;
LevelFrontend* frontend;
std::vector<HudElement> elements;
std::shared_ptr<InventoryView> inventoryView = nullptr;
UiDocument* inventoryDocument = nullptr;
std::shared_ptr<gui::UINode> createDebugPanel(Engine* engine);
std::shared_ptr<InventoryView> createContentAccess();
@@ -68,6 +101,9 @@ public:
void openInventory();
void closeInventory();
void add(HudElement element);
void remove(HudElement& element);
};
#endif /* SRC_HUD_H_ */