GoldFish Engine
Quite simple and lightweight game engine
Loading...
Searching...
No Matches
gf_gui.c
1#define GF_EXPOSE_GUI
2#define GF_EXPOSE_DRAW
3#define GF_EXPOSE_INPUT
4
5#include <gf_pre.h>
6
7/* External library */
8
9/* Interface */
10#include <gf_gui.h>
11
12/* Engine */
13#include <gf_graphic.h>
14#include <gf_draw.h>
15#include <gf_log.h>
16
17/* Standard */
18#include <stdlib.h>
19#include <string.h>
20
21gf_graphic_color_t gf_gui_base_color;
22gf_graphic_color_t gf_gui_font_color;
23
24gf_gui_t* gf_gui_create(gf_engine_t* engine, gf_draw_t* draw) {
25 gf_gui_t* gui = malloc(sizeof(*gui));
27 memset(gui, 0, sizeof(*gui));
28 gui->engine = engine;
29 gui->draw = draw;
30
31 gui->pressed = -1;
32
33 GF_SET_COLOR(gf_gui_base_color, 48, 96, 48, 255);
34 GF_SET_COLOR(gf_gui_font_color, 256 - 32, 256 - 32, 256 - 32, 255);
35
36 for(i = 0; i < GF_GUI_MAX_COMPONENTS; i++) gui->area[i].type = -1;
37
38 return gui;
39}
40
41/* note... left top should be the lightest in the border */
42
43void gf_gui_draw_box(gf_gui_t* gui, int mul, double x, double y, double w, double h) {
44 const int color_diff = 32; /* color diff */
45 const double bw = 2; /* border width */
47
48 int cd = mul * color_diff;
49
50 col = gf_gui_base_color;
51 col.r += cd;
52 col.g += cd;
53 col.b += cd;
54 gf_graphic_fill_rect(gui->draw, x, y, w, h, col);
55
56 col = gf_gui_base_color;
57 col.r -= cd;
58 col.g -= cd;
59 col.b -= cd;
60 gf_graphic_fill_polygon(gui->draw, col, GF_GRAPHIC_2D, 5, x + w, y + h, x + w, y, x + w - bw, y + bw, x + bw, y + h - bw, x, y + h);
61
62 col = gf_gui_base_color;
63 gf_graphic_fill_rect(gui->draw, x + bw, y + bw, w - bw * 2, h - bw * 2, col);
64}
65
66gf_gui_component_t* gf_gui_first_unused(gf_gui_t* gui, gf_gui_id_t* id) {
68 for(i = 0; i < GF_GUI_MAX_COMPONENTS; i++) {
69 if(gui->area[i].type == GF_GUI_UNUSED) {
70 *id = i;
71 return &gui->area[i];
72 }
73 }
74 return NULL;
75}
76
77gf_gui_id_t gf_gui_create_button(gf_gui_t* gui, double x, double y, double w, double h, const char* text) {
78 gf_gui_id_t id;
79 gf_gui_component_t* c = gf_gui_first_unused(gui, &id);
80
81 c->type = GF_GUI_BUTTON;
82 c->x = x;
83 c->y = y;
84 c->width = w;
85 c->height = h;
86
87 c->pressed = 0;
88 c->callback = NULL;
89
90 c->u.button.text = malloc(strlen(text) + 1);
91 strcpy(c->u.button.text, text);
92 return id;
93}
94
95void gf_gui_render(gf_gui_t* gui) {
97 gf_input_t* input = gui->draw->input;
98 for(i = GF_GUI_MAX_COMPONENTS - 1; i >= 0; i--) {
99 gf_gui_component_t* c = &gui->area[i];
100 double cx = c->x;
101 double cy = c->y;
102 double cw = c->width;
103 double ch = c->height;
104 switch(c->type) {
105 case GF_GUI_BUTTON: {
106 if(input->mouse_x != -1 && input->mouse_y != -1 && gui->pressed == -1 && (input->mouse_flag & GF_INPUT_MOUSE_LEFT_MASK) && (cx <= input->mouse_x && input->mouse_x <= cx + cw) && (cy <= input->mouse_y && input->mouse_y <= cy + ch)) {
107 gui->pressed = i;
108 } else if(gui->pressed == -1) {
109 c->pressed = 0;
110 }
111 break;
112 }
113 }
114 }
115 for(i = 0; i < GF_GUI_MAX_COMPONENTS; i++) {
116 gf_gui_component_t* c = &gui->area[i];
117 double cx = c->x;
118 double cy = c->y;
119 double cw = c->width;
120 double ch = c->height;
121 switch(c->type) {
122 case GF_GUI_BUTTON: {
123 double x = cx + cw / 2 - gf_graphic_text_width(gui->draw, GF_GUI_FONT_SIZE, c->u.button.text) / 2;
124 double y = cy + ch / 2 - GF_GUI_FONT_SIZE / 2;
125 gf_gui_draw_box(gui, (gui->pressed == i) ? GF_GUI_INVERT : GF_GUI_NORMAL, cx, cy, cw, ch);
126 gf_graphic_text(gui->draw, x, y, GF_GUI_FONT_SIZE, c->u.button.text, gf_gui_font_color);
127 break;
128 }
129 }
130 }
131 if((gui->pressed != -1) && !(input->mouse_flag & GF_INPUT_MOUSE_LEFT_MASK)) {
132 if(gui->area[gui->pressed].callback != NULL) {
133 gui->area[gui->pressed].callback(gui->engine, gui->draw, gui->pressed, GF_GUI_PRESS_EVENT);
134 }
135 gui->area[gui->pressed].pressed = 1;
136 gui->pressed = -1;
137 }
138}
139
140void gf_gui_set_callback(gf_gui_t* gui, gf_gui_id_t id, gf_gui_callback_t callback) { gui->area[id].callback = callback; }
Drawing interface.
Graphic interface.
#define GF_SET_COLOR(color, red, green, blue, alpha)
Macro to set color safely and shorter.
Definition gf_graphic.h:39
#define GF_GRAPHIC_2D
Dimension parameter for 2D.
Definition gf_graphic.h:26
#define GF_GUI_INVERT
Draw border inverted.
Definition gf_gui.h:32
#define GF_GUI_FONT_SIZE
Default GUI font size.
Definition gf_gui.h:38
#define GF_GUI_NORMAL
Draw border normally.
Definition gf_gui.h:26
Logger.
Required headers before anything.
int gf_gui_id_t
Component ID.
Definition gui.h:17
#define GF_GUI_MAX_COMPONENTS
Max components engine GUI can handle.
Definition gui.h:48
#define GF_INPUT_MOUSE_LEFT_MASK
Mask for left mouse button.
Definition input.h:28
Drawing interface.
Definition draw.h:108
gf_input_t * input
Input interface.
Definition draw.h:108
Engine instance.
Definition core.h:46
double g
Green.
Definition graphic.h:44
double b
Blue.
Definition graphic.h:44
double r
Red.
Definition graphic.h:44
char * text
Button text.
Definition gui.h:67
Component.
Definition gui.h:120
int pressed
1 if pressed, otherwise 0
Definition gui.h:120
double y
X coord of component.
Definition gui.h:120
double width
Width of component.
Definition gui.h:120
double height
Height of component.
Definition gui.h:120
gf_gui_callback_t callback
Event callback.
Definition gui.h:120
gf_gui_union_t u
Component union.
Definition gui.h:120
int type
Component type.
Definition gui.h:120
double x
X coord of component.
Definition gui.h:120
GUI.
Definition gui.h:144
gf_gui_id_t pressed
1 if something is being pressed, otherwise 0
Definition gui.h:144
gf_engine_t * engine
Engine instance.
Definition gui.h:144
gf_draw_t * draw
Drawing interface.
Definition gui.h:144
gf_gui_component_t area[64]
Created components.
Definition gui.h:144
Input interface.
Definition input.h:64
int mouse_flag
Mouse flag.
Definition input.h:64
int mouse_y
Y coord of mouse.
Definition input.h:64
int mouse_x
X coord of mouse.
Definition input.h:64
gf_gui_button_t button
Button component.
Definition gui.h:78