pgpl/include/pgpl/gui/predef.h
2025-10-03 20:16:11 +02:00

131 lines
5.3 KiB
C

#ifndef PGPL_GUI_PREDEF_H
#define PGPL_GUI_PREDEF_H
#include <pgpl/render/predef.h>
#include <pgpl/thread.h>
#include <pgpl/vector.h>
#include <pgpl/window/predef.h>
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Predefinition of some structs. */
typedef struct PGPL_GuiWidget PGPL_GuiWidget;
typedef struct PGPL_Gui PGPL_Gui;
/* These are the enum values for the GUI colors. This helps select a different
* color from the theme if a widget is currently active, hovered over, or in a
* default state. */
typedef enum PGPL_GuiStatusColor {
PGPL_GUI_STATUS_COLOR_NORMAL,
PGPL_GUI_STATUS_COLOR_HOVER,
PGPL_GUI_STATUS_COLOR_ACTIVE
} PGPL_GuiStatusColor;
/* This controls what font size from the theme should be used. There are three
* different types. */
typedef enum PGPL_GuiFontSize {
PGPL_GUI_FONT_SIZE_TITLE,
PGPL_GUI_FONT_SIZE_HEADING,
PGPL_GUI_FONT_SIZE_CONTENT
} PGPL_GuiFontSize;
/* This is the struct for the themes. This controls the colors, font sizes, font
* and many more settings that widgets in a GUI render with. You can use the
* helper function pgpl_gui_theme_configure to easily configure such a theme
* struct. */
typedef struct PGPL_GuiTheme {
/* Color for the text and borders, array of 3 colors to support all values
* from PGPL_GuiStatusColor. */
PGPL_Color text_color[3];
/* Color for the background of widgets, array of 3 colors to support all
* values from PGPL_GuiStatusColor. */
PGPL_Color widget_background_color[3];
/* Color for the background of a GUI. */
PGPL_Color background_color;
/* Controls the margin of the widgets. */
PGPL_Rectangle margin;
/* Controls the border of the widgets. */
PGPL_Rectangle border;
/* Controls the padding of the widgets. */
PGPL_Rectangle padding;
/* Controls the font size of the widgets, this is an array of three so that it
* can support all values from PGPL_GuiFontSize. */
double font_size[3];
/* The font of the theme. */
PGPL_Font *font;
} PGPL_GuiTheme;
/* This is the struct for the individual widgets. This can be used to create
* custom widgets as well. Do note that if you create a custom struct for your
* widget, you need to ensure that the first attribute of said struct is of type
* PGPL_GuiWidget, so that other containers and the gui itself can call its
* methods and read its attributes. */
struct PGPL_GuiWidget {
/* This should be a unique string, often the name of the struct, so that the
* widget type can be identified. */
const char *id;
/* This is the rendering offset of the widget. */
double offset_x, offset_y;
/* expand_x and expand_y determine if the widget should expand in the x and y
* direction when being rendered. */
bool expand_x, expand_y;
/* This determines if the border and background of the widget should be
* rendered or not. */
bool border, background;
/* This picks out which font size from the theme to use. */
PGPL_GuiFontSize font_size;
/* This picks out which color from the theme to use. */
PGPL_GuiStatusColor gui_color;
/* This is the theme that should be used instead of the main theme. Note that
* this theme should propagate to any possible child widgets as well. */
PGPL_GuiTheme theme_override;
/* This determines if the override theme should even be used. If this is
* false, the theme_override is simply ignored. */
bool use_theme_override;
/* These attributes determine whether or not margin, border and padding sizes
* respectively should be ignored when rendering. */
bool ignore_margin, ignore_border, ignore_padding;
/* This returns the size of the content of a widget. This should NOT include
* any margin, padding or border size. */
void (*get_content_size)(PGPL_GuiWidget *widget, PGPL_GuiTheme *theme,
double *width, double *height, double max_width,
double max_height);
/* This renders the content of the widget. Note that the margin, border,
* padding, background and offset of the widget must be accounted for BEFORE
* calling this function. For ease, you can use the
* pgpl_gui_widget_render_full function to automatically take care of all of
* those things for you. */
void (*render_content)(PGPL_GuiWidget *widget, PGPL_Renderer *renderer,
PGPL_GuiTheme *theme, double x, double y,
double max_width, double max_height);
/* This should get called for every event that is not a render or close event.
* Note that the x and y values should be called with the widgets offset
* pre-included. */
void (*event)(PGPL_GuiWidget *widget, PGPL_GuiTheme *theme, PGPL_Gui *gui,
PGPL_WindowEventType event_type,
PGPL_WindowEventData *event_data, double x, double y,
double max_width, double max_height);
/* This should destroy the widget, freeing all of its resources and also call
* the destroy method on all of its potential child widgets. */
void (*destroy)(PGPL_GuiWidget *widget);
};
/* This is the struct for the gui itself. Do not modify it's mutex and the
* widgets vector. The app_data value is used for event callbacks. */
struct PGPL_Gui {
PGPL_WindowThread *window_thread;
PGPL_GuiTheme theme;
PGPL_Vector *widgets;
void *app_data;
PGPL_Mutex *mutex;
};
#ifdef __cplusplus
}
#endif
#endif