ui nodes 'gravity' write-only property
This commit is contained in:
parent
7601bfad3a
commit
eba8332b75
@ -190,3 +190,50 @@ void UINode::reposition() {
|
||||
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,6 +24,22 @@ namespace gui {
|
||||
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 {
|
||||
/// @brief element identifier used for direct access in UiDocument
|
||||
@ -161,6 +177,8 @@ namespace gui {
|
||||
|
||||
/* Fetch pos from positionfunc if assigned */
|
||||
void reposition();
|
||||
|
||||
virtual void setGravity(Gravity gravity);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -22,6 +22,25 @@ static Align align_from_string(const std::string& str, Align 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 */
|
||||
static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) {
|
||||
if (element->has("id")) {
|
||||
@ -67,6 +86,12 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no
|
||||
}
|
||||
std::string alignName = element->attr("align", "").getText();
|
||||
node.setAlign(align_from_string(alignName, node.getAlign()));
|
||||
|
||||
if (element->has("gravity")) {
|
||||
node.setGravity(gravity_from_string(
|
||||
element->attr("gravity").getText()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -229,10 +229,7 @@ Hud::Hud(Engine* engine, LevelFrontend* frontend, Player* player)
|
||||
gui->add(grabbedItemView);
|
||||
|
||||
auto dgrapher = std::make_shared<DeltaGrapher>(350, 250, 2000);
|
||||
dgrapher->setPositionFunc([=]() {
|
||||
glm::vec2 size = dgrapher->getSize();
|
||||
return glm::vec2(Window::width-size.x, Window::height-size.y);
|
||||
});
|
||||
dgrapher->setGravity(gui::Gravity::bottom_right);
|
||||
add(HudElement(hud_element_mode::permanent, nullptr, dgrapher, true));
|
||||
}
|
||||
|
||||
@ -254,7 +251,49 @@ void Hud::cleanup() {
|
||||
return e.isRemoved();
|
||||
});
|
||||
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) {
|
||||
auto level = frontend->getLevel();
|
||||
@ -268,31 +307,16 @@ void Hud::update(bool visible) {
|
||||
if (pause && menu->getCurrent().panel == nullptr) {
|
||||
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 (Events::jactive(BIND_HUD_INVENTORY)) {
|
||||
if (inventoryOpen) {
|
||||
closeInventory();
|
||||
} else {
|
||||
openInventory();
|
||||
}
|
||||
}
|
||||
if (!gui->isFocusCaught()) {
|
||||
processInput(visible);
|
||||
}
|
||||
if ((pause || inventoryOpen) == Events::_cursor_locked) {
|
||||
Events::toggleCursor();
|
||||
}
|
||||
|
||||
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) {
|
||||
closeInventory();
|
||||
}
|
||||
@ -308,25 +332,6 @@ void Hud::update(bool visible) {
|
||||
contentAccess->setMinSize(glm::vec2(1, Window::height));
|
||||
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) {
|
||||
for (auto& element : elements) {
|
||||
element.update(pause, inventoryOpen, player->debug);
|
||||
@ -348,11 +353,6 @@ void Hud::openInventory() {
|
||||
add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false));
|
||||
}
|
||||
|
||||
/// @brief Show player inventory + block UI
|
||||
/// @param block world position of the open block
|
||||
/// @param doc block UI document (root element must be an InventoryView)
|
||||
/// @param blockinv block inventory.
|
||||
/// If blockinv is nullptr a new virtual inventory will be created
|
||||
void Hud::openInventory(
|
||||
glm::ivec3 block,
|
||||
UiDocument* doc,
|
||||
@ -378,7 +378,7 @@ void Hud::openInventory(
|
||||
}
|
||||
level->chunks->getChunkByVoxel(block.x, block.y, block.z)->setUnsaved(true);
|
||||
blockUI->bind(blockinv, frontend, interaction.get());
|
||||
currentblock = block;
|
||||
blockPos = block;
|
||||
currentblockid = level->chunks->get(block.x, block.y, block.z)->id;
|
||||
add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false));
|
||||
}
|
||||
@ -427,13 +427,13 @@ void Hud::add(HudElement element) {
|
||||
scripting::on_ui_open(
|
||||
element.getDocument(),
|
||||
inventory.get(),
|
||||
currentblock
|
||||
blockPos
|
||||
);
|
||||
} else {
|
||||
scripting::on_ui_open(
|
||||
element.getDocument(),
|
||||
nullptr,
|
||||
currentblock
|
||||
blockPos
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ class Hud {
|
||||
/// @brief Block inventory view
|
||||
std::shared_ptr<InventoryView> blockUI = nullptr;
|
||||
/// @brief Position of the block open
|
||||
glm::ivec3 currentblock {};
|
||||
glm::ivec3 blockPos {};
|
||||
/// @brief Id of the block open (used to detect block destruction or replacement)
|
||||
blockid_t currentblockid = 0;
|
||||
|
||||
@ -107,6 +107,7 @@ class Hud {
|
||||
std::shared_ptr<InventoryView> createContentAccess();
|
||||
std::shared_ptr<InventoryView> createHotbar();
|
||||
|
||||
void processInput(bool visible);
|
||||
void updateElementsPosition(const Viewport& viewport);
|
||||
void cleanup();
|
||||
public:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user