#pragma once #include #include typedef uint8_t uiChannel; typedef struct uiPixel { uiChannel r, g, b, a; } uiPixel; typedef struct uiSize { int width; int height; } uiSize; /// A UI surface to which widgets are rendered. typedef struct uiSurface { int width; int height; uiPixel* pixels; } uiSurface; /// Rectangle. /// (x,y) is the top-left corner. typedef struct uiRect { int x; int y; int width; int height; } uiRect; /// Point. typedef struct uiPoint { int x; int y; } uiPoint; /// Widget ID. typedef int uiWidgetId; /// Widget type. typedef enum uiWidgetType { uiTypeButton, uiTypeEdit, uiTypeFrame, uiTypeLabel, uiTypeLayout, uiTypeTable, uiTypeMax, } uiWidgetType; typedef struct uiButton uiButton; typedef struct uiEdit uiEdit; typedef struct uiFrame uiFrame; typedef struct uiLabel uiLabel; typedef struct uiLayout uiLayout; typedef struct uiTable uiTable; typedef struct uiWidget uiWidget; /// Widget pointer. typedef struct uiPtr { uiWidgetType type; union { uiButton* button; uiEdit* edit; uiFrame* frame; uiLabel* label; uiLayout* layout; uiTable* table; uiWidget* widget; }; } uiPtr; /// Direction in which a layout widget lays out its children. typedef enum uiLayoutDirection { uiVertical, uiHorizontal, } uiLayoutDirection; /// Directions in which a widget stretches. /// /// Stretch determines how the widget occupies the area of its parent widget. /// /// uiStretchNone - the widget has a fixed size. /// uiStretchX/Y - the widget stretches in the X/Y direction. typedef enum uiStretch { uiStretchNone = 0, uiStretchX = 1, uiStretchY = 2, } uiStretch; /// Mouse button. typedef enum uiMouseButton { uiLMB, uiRMB, uiMouseButtonMax, } uiMouseButton; /// Mouse button state. typedef enum uiMouseButtonState { uiMouseUp, uiMouseDown, } uiMouseButtonState; /// Mouse button event. typedef struct uiMouseButtonEvent { uiMouseButton button; uiMouseButtonState button_state; uiPoint mouse_position; } uiMouseButtonEvent; /// Mouse click event. typedef struct uiMouseClickEvent { uiMouseButton button; uiPoint mouse_position; } uiMouseClickEvent; /// Mouse scroll event. typedef struct uiMouseScrollEvent { uiPoint mouse_position; int scroll_offset; /// Positive = down; negative = up. } uiMouseScrollEvent; /// Mouse move event. typedef struct uiMouseMoveEvent { // TODO: A bitfield would be sufficient. uiMouseButtonState button_state[uiMouseButtonMax]; uiPoint mouse_position; } uiMouseMoveEvent; /// Input event type. typedef enum uiInputEventType { uiEventMouseButton, uiEventMouseClick, uiEventMouseScroll, uiEventMouseMove, } uiInputEventType; /// Input event. typedef struct uiInputEvent { uiInputEventType type; union { uiMouseButtonEvent mouse_button; uiMouseClickEvent mouse_click; uiMouseScrollEvent mouse_scroll; uiMouseMoveEvent mouse_move; }; } uiInputEvent; /// Table click event. typedef struct uiTableClickEvent { int col; int row; } uiTableClickEvent; /// UI event type. typedef enum uiWidgetEventType { uiWidgetEventClick, } uiWidgetEventType; /// UI event. /// These are events from the UI widgets back to the client application. typedef struct uiWidgetEvent { uiWidgetEventType type; uiPtr widget; union { uiTableClickEvent table_click; }; } uiWidgetEvent; /// Common construction parameters for widgets. typedef struct uiParams { uiStretch stretch; } uiParams; // ----------------------------------------------------------------------------- // Library. bool uiInit(void); void uiShutdown(void); // ----------------------------------------------------------------------------- // Widget. uiPtr uiMakeButtonPtr(uiButton*); uiPtr uiMakeEditPtr(uiEdit*); uiPtr uiMakeFramePtr(uiFrame*); uiPtr uiMakeLabelPtr(uiLabel*); uiPtr uiMakeLayoutPtr(uiLayout*); uiPtr uiMakeTablePtr(uiTable*); uiPtr uiMakeWidgetPtr(uiWidget*); uiPtr uiNullptr(void); bool uiIsNullptr(uiPtr); uiButton* uiGetButtonPtr(uiPtr); uiEdit* uiGetEditPtr(uiPtr); uiFrame* uiGetFramePtr(uiPtr); uiLabel* uiGetLabelPtr(uiPtr); uiLayout* uiGetLayoutPtr(uiPtr); uiTable* uiGetTablePtr(uiPtr); uiWidgetType uiWidgetGetType(const uiWidget*); void uiPrint(uiPtr); // ----------------------------------------------------------------------------- // Frame. uiFrame* uiMakeFrame(void); void uiDestroyFrame(uiFrame**); uiSize uiGetFrameSize(const uiFrame*); // ----------------------------------------------------------------------------- // Layout. uiLayout* uiMakeLayout(uiPtr parent, uiLayoutDirection); // ----------------------------------------------------------------------------- // Button. uiButton* uiMakeButton(uiPtr parent, const char* text, const uiParams*); // ----------------------------------------------------------------------------- // Label. uiLabel* uiMakeLabel(uiPtr parent, const char* text); const char* uiLabelGetText(const uiLabel*); // ----------------------------------------------------------------------------- // Table. uiTable* uiMakeTable(uiPtr parent, int rows, int cols, const char** header); void uiTableClear(uiTable*); void uiTableAddRow(uiTable*, const char** row); void uiTableSet(uiTable*, int row, int col, const char* text); const char* uiTableGet(const uiTable*, int row, int col); void uiTableScroll(uiTable*, int row); // ----------------------------------------------------------------------------- // Layout. /// Lay out the widgets in the frame given the frame's new width and height. /// /// This should typically be called whenever the window is resized. void uiLayOut(uiFrame*, int width, int height); // ----------------------------------------------------------------------------- // Rendering. void uiRender(const uiFrame*, uiSurface*); // ----------------------------------------------------------------------------- // UI and user events. /// Get the widget events. /// Return the number of events in the returned array. /// /// This function clears the events recorded by the UI library since the last /// input event. Subsequent calls to this function, with no further user input, /// therefore report zero widget events. int uiGetEvents(uiWidgetEvent const**); /// Send an input event to the UI. /// Return true if the UI requires a redraw. bool uiSendEvent(uiFrame*, const uiInputEvent*);