9#ifndef VK_NO_PROTOTYPES
10 #define VK_NO_PROTOTYPES 1
12#define VMA_STATIC_VULKAN_FUNCTIONS 0
13#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
14#include <vk_mem_alloc.h>
17#include <unordered_map>
20#include <nlohmann/json.hpp>
31#include "../../../thirdparty/stb/stb_truetype.h"
45 UIUnitValue() =
default;
46 UIUnitValue(
float v) : value(v), type(UIUnitType::Psp) {}
47 UIUnitValue(
float v,
UIUnitType t) : value(v), type(t) {}
50 UIUnitValue& operator=(
float v) {
56 void parse(
const nlohmann::json& jval);
58 static UIUnitValue parseJson(
const nlohmann::json& jval) {
59 UIUnitValue v; v.
parse(jval);
return v;
63 nlohmann::json
toJson()
const;
77 stbtt_fontinfo info{};
78 std::vector<stbtt_bakedchar> cdata;
79 VkImage image = VK_NULL_HANDLE;
80 VmaAllocation alloc = VK_NULL_HANDLE;
81 VkImageView view = VK_NULL_HANDLE;
83 int width = 0, height = 0;
87 float bakedSize = 0.f;
92 glm::vec4 color{1,1,1,1};
93 glm::vec4 bgColor{-1,-1,-1,-1};
94 glm::vec4 borderColor = {0,0,0,0};
105 uint32_t vertexOffset;
120 float rotation = 0.f;
123 nlohmann::json nodeJson;
126 std::vector<Widget*> children;
128 std::function<void()> onClick =
nullptr;
129 std::function<void()> onFocusEnter =
nullptr;
130 std::function<void()> onFocusLost =
nullptr;
135 void applyLayout(
VexUI* uiManager);
153 void load(
const std::string& path);
159 void render(VkCommandBuffer cmd, VkPipeline pipeline, VkPipelineLayout pipelineLayout,
int currentFrame);
171 void setText(
const std::string&
id,
const std::string& txt);
176 void setOnClick(
const std::string&
id, std::function<
void()> cb);
183 log(
"Widget not found");
192 log(
"Widget not found");
203 pendingSetters.push_back([
this,
id, style]() {
212 void setRotation(
const std::string&
id,
float degrees);
229 void setImage(
const std::string&
id,
const std::string& path);
235 void setFont(
const std::string&
id,
const std::string& fontPath,
UIUnitValue fontSize);
240 void setColor(
const std::string&
id, glm::vec4 color);
264 if(initialized) { this->zIndex = zIndex; }
265 else { pendingSetters.push_back([
this, zIndex]() { this->zIndex = zIndex; }); }
272 if (m_gamepadNavigationCooldown > 0.0f) m_gamepadNavigationCooldown -= deltaTime;
277 for (
auto& setter : pendingSetters) setter();
278 pendingSetters.clear();
282 float getPspMultiplier()
const;
283 glm::uvec2 getRenderResolution()
const {
return m_ctx.currentRenderResolution; }
286 VulkanContext& m_ctx;
287 VirtualFileSystem* m_vfs;
288 VulkanResources* m_res;
289 ResolutionManager* m_resMgr;
291 Widget* m_root =
nullptr;
292 bool initialized =
false;
295 glm::uvec2 m_lastRenderRes{0, 0};
296 float m_lastPspMult = 0.f;
298 std::vector<std::function<void()>> pendingSetters;
300 bool loadPending =
false;
301 std::string loadPath =
"";
303 std::unordered_map<std::string, FontAtlas> m_fontAtlases;
305 VkBuffer m_vb = VK_NULL_HANDLE;
306 VmaAllocation m_vbAlloc = VK_NULL_HANDLE;
308 VkSampler m_uiSampler = VK_NULL_HANDLE;
310 Widget* m_focusedWidget =
nullptr;
311 float m_gamepadAxisX = 0.0f;
312 float m_gamepadAxisY = 0.0f;
313 Widget* m_previousFocusedWidget =
nullptr;
314 float m_gamepadNavigationCooldown = 0.0f;
315 static constexpr float GAMEPAD_NAV_COOLDOWN = 0.2f;
316 static constexpr float GAMEPAD_AXIS_THRESHOLD = 0.5f;
328 void layout(glm::uvec2 res);
334 void batch(Widget* w, std::vector<float>& verts, glm::vec2 parentOffset = {0.f, 0.f});
343 Widget*
parseNode(
const nlohmann::json& j);
354 Widget*
findWidgetAt(Widget* w, glm::vec2 pos, glm::vec2 parentOffset = {0.f, 0.f});
360 Widget*
findById(Widget* w,
const std::string&
id);
367 std::vector<std::string>
wrapText(
const std::string& text,
const FontAtlas& a,
float maxWidth);
379 static void measureTextNode(LayoutNode* node,
float width,
float height);
384 void safeUpdate(
const std::string&
id, std::function<
void(Widget*)> action);
404 Widget*
findClosestNavigableWidget(
const glm::vec2& fromPos,
const glm::vec2& direction,
const std::vector<Widget*>& candidates);
Main header for the Entity Component System (ECS) framework.
This file defines ResolutionManager class and ResolutionMode struct.
This file defines VulkanResources Class.
This file defines VirtualFileSystem and VPKStream classes.
Class responsible for managing resolution settings, calculating render resolution based on selected m...
Class defining VexUI, it initializes the UI system, loads, renders, converts ui data,...
void setStyle(const std::string &id, const UIStyle &style)
Set a UI element's style.
VexUI(VulkanContext &ctx, VirtualFileSystem *vfs, VulkanResources *res, ResolutionManager *resMgr)
Constructor for VexUI.
void setColor(const std::string &id, glm::vec4 color)
Set text/tint color.
void setSize(const std::string &id, UIUnitValue w, UIUnitValue h)
Resize a widget.
void setRotation(const std::string &id, float degrees)
Set rotation of a widget in degrees.
void loadImages(Widget *w)
Loads images for the UI.
bool isWidgetNavigable(Widget *w) const
Check if widget is navigable (button type).
void batch(Widget *w, std::vector< float > &verts, glm::vec2 parentOffset={0.f, 0.f})
Batches the UI for rendering.
void setZIndex(int zIndex)
Set the z-index of the UI system.
glm::vec2 calculateTextSize(Widget *w, float maxWidth=FLT_MAX)
Calculates the size of the text.
int getZIndex()
Get the current z-index of the UI system.
void setText(const std::string &id, const std::string &txt)
Set text of a UI element.
bool init()
Initialize the UI system, components needed later on.
void getNavigableWidgets(std::vector< Widget * > &out)
Get all navigable widgets (buttons).
void setPosition(const std::string &id, UIUnitValue x, UIUnitValue y)
Move a widget (sets Left/Top yoga properties). Works best with position: absolute,...
static void measureTextNode(LayoutNode *node, float width, float height)
Measures a text node.
Widget * findById(Widget *w, const std::string &id)
Finds a widget by its id.
void loadFonts(Widget *w)
Loads fonts for the UI.
void processEvent(const SDL_Event &ev)
Process mouse and keyboard events.
Widget * getFocusedWidget() const
Get the currently focused widget.
bool isInitialized()
Check if the UI system is initialized.
void safeUpdate(const std::string &id, std::function< void(Widget *)> action)
Updates a widget safely.
void update(float deltaTime=0.016f)
Update the UI system.
void setFont(const std::string &id, const std::string &fontPath, UIUnitValue fontSize)
Change font properties.
Widget * findClosestNavigableWidget(const glm::vec2 &fromPos, const glm::vec2 &direction, const std::vector< Widget * > &candidates)
Find closest navigable widget in a direction.
void setBorder(const std::string &id, UIUnitValue width, glm::vec4 color)
Set border properties.
void navigateToWidget(float dirX, float dirY)
Navigate to widget in a given direction.
void freeTree(Widget *w)
Frees the widget tree.
void setOnClick(const std::string &id, std::function< void()> cb)
Set on-click callback of a UI element.
UIStyle * getStyle(const std::string &id)
Get a UI element's style.
Widget * parseNode(const nlohmann::json &j)
Parses a node from json to widgets.
void layout(glm::uvec2 res)
Layouts the UI using yoga.
void uploadVerts(const std::vector< float > &verts)
Uploads the vertex buffer to the GPU.
glm::vec2 getWidgetCenter(Widget *w)
Get widget center position in screen space.
std::vector< std::string > wrapText(const std::string &text, const FontAtlas &a, float maxWidth)
Wraps text to fit within a given width.
void setImage(const std::string &id, const std::string &path)
Change the image of an image widget.
void load(const std::string &path)
Load UI data from a JSON file.
Widget * findWidgetAt(Widget *w, glm::vec2 pos, glm::vec2 parentOffset={0.f, 0.f})
Finds a widget at a position.
Widget * getWidget(const std::string &id)
Get a UI element.
void setBackgroundColor(const std::string &id, glm::vec4 color)
Set background color.
void render(VkCommandBuffer cmd, VkPipeline pipeline, VkPipelineLayout pipelineLayout, int currentFrame)
Render the UI. It is called by main rendering function.
void collectNavigableWidgets(Widget *w, std::vector< Widget * > &out)
Recursively collect navigable widgets.
void setFocusedWidget(Widget *w)
Set focus to a widget and trigger focus callbacks.
This class provides abstraction of file system needed for loading packed and unpacked assets.
This class manages resources like textures, descriptor sets, and uniform buffers.
This file defines struct holding all vulkan data, like device, surface, swapchain,...
UIUnitType
Supported responsive UI unit types.
WidgetType
Enum specifying possible types of widgets.
void VEX_EXPORT log(const char *fmt,...)
Logs a formatted message.
TextAlign
Allows for text aligment.
Layout node representing a single UI element in the layout tree.
Quad component needed for rendering.
Basic UI styling component.
Struct storing unit value logic natively.
void parse(const nlohmann::json &jval)
Parses a json value into the unit struct.
nlohmann::json toJson() const
Converts the unit back to a json-compatible format (preserves strings like "px", "%").
float getPixels(const VexUI *ui) const
Dynamically calculates the raw pixel representation required for rendering.
2D representation of UIUnitValue to replace glm::vec2 size safely.
Struct holding all vulkan data, like device, surface, swapchain, images, views, and more.