File Widget.h

File List > engine > include > Widget.h

Go to the documentation of this file

#ifndef WIDGET_H
#define WIDGET_H
#ifdef __cplusplus
extern "C" {
#endif

#include "ObjectPool.h"
#include "HandleDefs.h"
#include <stdbool.h>
#include "DynArray.h"
#include "Geometry.h"


struct UIWidget;
struct WidgetPropertyBinding;
struct DataNode;



#ifdef  __cplusplus
typedef int(*PrintfFn)(const char* fmt, ...);

#else
typedef int(*PrintfFn)(const char* restrict fmt, ...);
#endif //  __cplusplus

struct Vert2DColourTexture;
typedef struct Vert2DColourTexture WidgetVertex;
struct Vert2DColourTextureQuad;
typedef struct Vert2DColourTextureQuad WidgetQuad;

typedef float(*GetUIWidgetDimensionFn)(struct UIWidget* pWidget, struct UIWidget* pParent);
typedef void(*LayoutChildrenFn)(struct UIWidget* pWidget, struct UIWidget* pParent);
typedef void(*OnDestroyWidgetFn)(struct UIWidget* pWidget);
typedef void*(*OutputWidgetVerticesFn)(struct UIWidget* pThisWidget, VECTOR(WidgetVertex) pOutVerts);
typedef void(*OnWidgetInitFn)(struct UIWidget* pWidget);
typedef void(*OnBoundPropertyChangedFn)(struct UIWidget* pThisWidget, struct WidgetPropertyBinding* pBinding);

typedef struct WidgetDim* (*WidgetDimGetterFn)(struct UIWidget* pWidget);

typedef void (*FocusedWidgetRecieveKeystrokeFn)(struct UIWidget* pWidget, int keystroke);

typedef void (*OnChildrenChangedFn)(struct UIWidget* pWidget);

struct WidgetDim* GetWidgetWidthDim(struct UIWidget* pWidget);
struct WidgetDim* GetWidgetHeightDim(struct UIWidget* pWidget);

struct WidgetPadding
{
    float paddingTop;
    float paddingBottom;
    float paddingLeft;
    float paddingRight;
};

struct WidgetScale
{
    float scaleX;
    float scaleY;
};

enum WidgetDimType
{
    WD_Auto,
    WD_Stretch,
    WD_Pixels,

    WD_StretchFraction,
    WD_Percentage
};

typedef enum WidgetHorizontalAlignment
{
    WHA_Left,
    WHA_Middle,
    WHA_Right
}WidgetHorizontalAlignment;

typedef enum WidgetVerticalAlignment
{
    WVA_Top,
    WVA_Middle,
    WVA_Bottom
}WidgetVerticalAlignment;

typedef enum WidgetDockPoint
{
    WDP_TopLeft,
    WDP_TopMiddle,
    WDP_TopRight,
    WDP_MiddleRight,
    WDP_BottomRight,
    WDP_BottomMiddle,
    WDP_BottomLeft,
    WDP_MiddleLeft,
    WDP_Centre
}WidgetDockPoint;

struct WidgetDim
{
    enum WidgetDimType type;
    float data;
};



#define LUA_CALLBACK_MAX_NAME_LEN 64
struct LuaWidgetCallback
{
    char name[LUA_CALLBACK_MAX_NAME_LEN + 1];
    size_t nameLen;
    bool bActive;
};

enum WidgetCallbackTypes
{
    WC_OnMouseEnter,
    WC_OnMouseLeave,
    WC_OnMouseMove,
    WC_OnMouseDown,
    WC_OnMouseUp,
    WC_OnGainFocus,
    WC_OnLeaveFocus,
    WC_NUM
};

typedef void (*WidgetMousePosCallbackFn)(struct UIWidget* pWidget, float x, float y);
typedef void (*WidgetMouseBtnCallbackFn)(struct UIWidget* pWidget, float x, float y, int btn);
typedef void (*WidgetFocusChangeCallbackFn)(struct UIWidget* pWidget);

struct CWidgetMouseCallback
{
    enum WidgetCallbackTypes type;
    union
    {
        WidgetMousePosCallbackFn mousePosFn;
        WidgetMouseBtnCallbackFn mouseBtnFn;
        WidgetFocusChangeCallbackFn focusChangeFn;

        u64 bActive;
    }callback;
};


struct CWidgetCallbacks
{
    struct CWidgetMouseCallback Callbacks[WC_NUM];

};

struct LuaWidgetCallbacks
{
    int viewmodelTable;
    struct LuaWidgetCallback Callbacks[WC_NUM];
};

// todo: make somehow glue this to the input system or change the input system to fit this 
#define NUM_BUTTONS 3
#define MAX_PROPERTY_NAME_LEN 32
#define MAX_NUM_BINDINGS 16

enum WidgetPropertyBindingType
{
    WBT_Int,
    WBT_Float,
    WBT_String,
    WBT_Bool,
    WBT_WidgetTree
};

struct WidgetPropertyBinding
{
    enum WidgetPropertyBindingType type;
    union
    {
        int i;
        float flt;
        char* str;
        bool bl;
    }data;
    char name[MAX_PROPERTY_NAME_LEN + 1];             // attribute content
    char boundPropertyName[MAX_PROPERTY_NAME_LEN + 1];// attribute name
};

struct WidgetMouseInfo
{
    float x;
    float y;
    int button;
};

struct UIWidget
{
    HWidget hNext;
    HWidget hPrev;
    HWidget hParent;
    HWidget hFirstChild;
    HWidget hThis;
    void* pImplementationData;
    GetUIWidgetDimensionFn fnGetWidth;
    GetUIWidgetDimensionFn fnGetHeight;
    LayoutChildrenFn fnLayoutChildren;
    OnDestroyWidgetFn fnOnDestroy;
    OutputWidgetVerticesFn fnOutputVertices;
    OnBoundPropertyChangedFn fnOnBoundPropertyChanged;
    OnWidgetInitFn fnOnWidgetInit; // called once whole widget tree is constructed
    FocusedWidgetRecieveKeystrokeFn fnRecieveKeystroke;
    OnChildrenChangedFn fnOnWidgetChildrenChangedFn;
    float top;
    float left;
    WidgetDockPoint dockPoint;
    struct WidgetPadding padding;
    struct LuaWidgetCallbacks scriptCallbacks;
    struct CWidgetCallbacks cCallbacks;
    struct WidgetPropertyBinding bindings[MAX_NUM_BINDINGS];
    struct WidgetDim width;
    struct WidgetDim height;
    size_t numBindings;
    float offsetX;
    float offsetY;
    WidgetHorizontalAlignment horizontalAlignment;
    WidgetVerticalAlignment verticalAlignment;
    bool bAcceptsFocus;
    bool bHasFocus;
};


void UI_Init();


void UI_DestroyWidget(HWidget widget);

HWidget UI_GetScratchWiget();

HWidget UI_NewBlankWidget();

size_t UI_CountWidgetChildrenPtr(struct UIWidget* pWidget);

size_t UI_CountWidgetChildren(HWidget pWidget);

struct UIWidget* UI_GetWidget(HWidget hWidget);

struct UIWidget* UI_FirstChild(HWidget hWidget);

void UI_AddChild(HWidget hParent, HWidget hChild);

float UI_ResolveWidthDimPxls(struct UIWidget* pWidget, const struct WidgetDim* dim);

float UI_ResolveHeightDimPxls(struct UIWidget* pWidget, const struct WidgetDim* dim);


void UI_WidgetCommonInit(struct DataNode* pInNode, struct UIWidget* outWidget);

void UI_DebugPrintCommonWidgetInfo(const struct UIWidget* inWidget, PrintfFn pPrintfFn);

void* UI_Helper_OnOutputVerts(struct UIWidget* pWidget, VECTOR(WidgetVertex) pOutVerts);

void UI_Helper_OnLayoutChildren(struct UIWidget* pWidget, struct UIWidget* pParent);

void UI_GetWidgetSize(HWidget hWidget, float* pOutW, float* pOutH);

void UI_GetWidgetTopLeft(HWidget hWidget, float* pOutLeft, float* pOutTop);

void UI_GetWidgetPadding(HWidget hWidget, float* pOutPaddingTop, float* pOutPaddingBottom, float* pOutPaddingLeft, float* pOutPaddingRight);

void UI_SendWidgetMouseEvent(struct UIWidget* pWidget, enum WidgetCallbackTypes type, struct WidgetMouseInfo* pMouseInfo);

void UI_GetHitBox(GeomRect outRect, HWidget hWidget);

bool UI_IsAttributeStringABindingExpression(const char* attributeValue);

void UI_AddStringPropertyBinding(struct UIWidget* pWidget, char* inBoundPropertyName, char* inBindingExpression, char** pOutData, int viewmodelTableIndex);

void UI_AddIntPropertyBinding(struct UIWidget* pWidget, char* inBoundPropertyName, char* inBindingExpression, int* pOutData, int viewmodelTableIndex);

void UI_AddFloatPropertyBinding(struct UIWidget* pWidget, char* inBoundPropertyName, char* inBindingExpression, float* pOutData, int viewmodelTableIndex);

char* UI_MakeBindingGetterFunctionName(const char* inBindingName);

char* UI_MakeBindingSetterFunctionName(const char* inBindingName);

struct WidgetPropertyBinding* UI_FindBinding(struct UIWidget* pWidget, const char* bindingName);

void UI_DefaultOnChildrenChanged(struct UIWidget* outWidget);

#ifdef __cplusplus
}
#endif

#endif