cbb0862cc91907a07a6125b1162b49a6bc22299a
[vg.git] / vg_imgui.h
1 /* Copyright (C) 2021-2024 Harry Godden (hgn) - All Rights Reserved */
2
3 /*
4 * Principles:
5 *
6 * 1. layout is defined by subdividing
7 * 2. a parent node should never be resized by the content after creation
8 * 3. when the ui is in an interactive state, no controls should ever move
9 * 4. controls directly reference a memory location and use that as their
10 * unique id
11 * 5. a maximum of ONE control per memory location can be drawn at any given
12 * point.
13 */
14
15 #pragma once
16
17 #include "vg_engine.h"
18 #include "vg_tex.h"
19 #include "vg_shader.h"
20 #include "vg_font.h"
21
22 extern vg_font_sheet vg_default_font_sheet;
23 extern vg_font_face vgf_default_small, vgf_default_large, vgf_default_title;
24
25 typedef i16 ui_px;
26 typedef ui_px ui_rect[4];
27 typedef ui_px ui_point[2];
28 typedef struct ui_vert ui_vert;
29
30 enum ui_axis {
31 k_ui_axis_h = 0x0u,
32 k_ui_axis_v = 0x1u,
33 };
34
35 /* Relative to cursor p0 */
36 enum ui_align
37 { /* DC BA */
38 k_ui_align_lwr = 0xff,
39 k_ui_align_left = 0x0000| 0x00,
40 k_ui_align_right = 0x0000| 0x01,
41 k_ui_align_center = 0x0000| 0x02,
42
43 k_ui_align_middle = 0x0100,
44 k_ui_align_middle_left = 0x0100| 0x00,
45 k_ui_align_middle_right = 0x0100| 0x01,
46 k_ui_align_middle_center = 0x0100| 0x02,
47
48 k_ui_align_bottom = 0x0200,
49 k_ui_align_bottom_left = 0x0200| 0x00,
50 k_ui_align_bottom_right = 0x0200| 0x01,
51 k_ui_align_bottom_center = 0x0200| 0x02,
52 };
53
54 #pragma pack(push,1)
55 struct ui_vert
56 {
57 ui_px co[2];
58 u16 uv[2];
59 u32 colour;
60 };
61 #pragma pack(pop)
62
63 enum ui_scheme_colour{
64 k_ui_bg = 0,
65 k_ui_fg = 8,
66 k_ui_hue = 16,
67 k_ui_red = 16,
68 k_ui_orange,
69 k_ui_yellow,
70 k_ui_green,
71 k_ui_aqua,
72 k_ui_blue,
73 k_ui_purple,
74 k_ui_gray,
75 k_ui_brighter = 8
76 };
77
78 enum ui_shader {
79 k_ui_shader_colour,
80 k_ui_shader_image,
81 k_ui_shader_hsv,
82 };
83
84 extern ui_px k_ui_widget_height,
85 k_ui_scale,
86 k_ui_padding;
87
88 typedef u32 ui_scheme[8*4];
89
90 #define UI_RGB( STDHEX ) 0xff000000 |\
91 ((STDHEX&0x000000ff)<<16) |\
92 ((STDHEX&0x0000ff00) ) |\
93 ((STDHEX&0x00ff0000)>>16)
94
95 #define UI_TEXTBOX_MULTILINE 0x1
96 #define UI_TEXTBOX_WRAP 0x2
97 #define UI_TEXTBOX_AUTOFOCUS 0x4
98
99 #define UI_MODAL_OK 0x0
100 #define UI_MODAL_GOOD 0x1
101 #define UI_MODAL_BAD 0x2
102 #define UI_MODAL_WARN 0x3
103 #define UI_MODAL_TYPE_BITS 0x3
104
105 #define UI_MOUSE_LEFT (SDL_BUTTON(SDL_BUTTON_LEFT))
106 #define UI_MOUSE_RIGHT (SDL_BUTTON(SDL_BUTTON_RIGHT))
107 #define UI_MOUSE_MIDDLE (SDL_BUTTON(SDL_BUTTON_MIDDLE))
108
109 #define UI_TOP 0x1
110 #define UI_LEFT 0x2
111 #define UI_BOTTOM 0x4
112 #define UI_RIGHT 0x8
113
114 struct vg_imgui
115 {
116 struct ui_vert *vertex_buffer;
117 u16 *indice_buffer;
118 u32 max_verts, max_indices,
119 cur_vert, cur_indice,
120 vert_start, indice_start;
121
122 union {
123 void *focused_control_id; /* uses the memory location of various locking
124 controls as an id */
125 char *textbuf;
126 i32 *ptr_enum;
127 };
128
129 u32 focused_control_hit;
130 enum ui_control_type{
131 k_ui_control_none,
132 k_ui_control_textbox,
133 k_ui_control_enum,
134 k_ui_control_modal
135 }
136 focused_control_type;
137
138 union{ /* controls that can be focused */
139 struct ui_textbuf{
140 int cursor_user, cursor_pos;
141 u32 len;
142 u32 flags;
143
144 struct ui_textbox_callbacks{
145 void (*enter)( char *, u32 ),
146 (*up)( char *, u32 ),
147 (*down)( char *, u32 ),
148 (*change)( char *, u32 ),
149 (*escape)( void );
150 }
151 callbacks;
152 }
153 textbox;
154
155 struct ui_enum{
156 struct ui_enum_opt{
157 i32 value;
158 const char *alias;
159 }
160 *options;
161 u32 option_count;
162 ui_rect rect;
163 }
164 _enum;
165 };
166
167 struct ui_modal{
168 const char *message;
169 u32 options;
170
171 struct ui_modal_callbacks{
172 void (*close)(u32);
173 }
174 callbacks;
175 }
176 modal;
177
178 GLuint tex_glyphs, vao, vbo, ebo, tex_bg;
179 v2f bg_inverse_ratio;
180
181 ui_px mouse[2], mouse_delta[2], mouse_click[2];
182 u32 mouse_state[2];
183 u32 ignore_input_frames;
184 bool mouse_pos_overriden;
185 int wants_mouse;
186
187 ui_rect click_fader, click_fader_end;
188 float click_fade_opacity;
189 f32 frosting;
190
191 ui_scheme scheme;
192 const vg_font_face *font;
193 v2f inverse_font_sheet;
194
195 enum ui_cursor{
196 k_ui_cursor_default,
197 k_ui_cursor_ibeam,
198 k_ui_cursor_hand,
199 k_ui_cursor_max
200 }
201 cursor;
202
203 SDL_Cursor *cursor_map[ k_ui_cursor_max ];
204 v4f colour;
205
206 f32 hue; /* lol this sucks */
207 }
208 extern vg_ui;
209
210 enum ui_button_state {
211 k_ui_button_none = 0x0,
212 k_ui_button_click = 0x1,
213 k_ui_button_holding_inside = 0x2,
214 k_ui_button_holding_outside = 0x4,
215 k_ui_button_hover = 0x8
216 };
217
218 /* TODO: docu.. */
219
220 void vg_ui_init(void);
221 void rect_copy( ui_rect a, ui_rect b );
222 void ui_flush( enum ui_shader shader, f32 w, f32 h );
223 struct ui_vert *ui_fill_rect( ui_rect rect, u32 colour, ui_px uv[4] );
224 struct ui_vert *ui_fill( ui_rect rect, u32 colour );
225 void ui_outline( ui_rect rect, ui_px thickness, u32 colour, u32 mask );
226 void ui_split( ui_rect rect, enum ui_axis other, ui_px width, ui_px gap,
227 ui_rect l, ui_rect r );
228 void ui_rect_center( ui_rect parent, ui_rect rect );
229 void ui_fit_item( ui_rect rect, ui_px size[2], ui_rect d );
230 void ui_split_ratio( ui_rect rect, enum ui_axis dir, float ratio,
231 ui_px gap, ui_rect l, ui_rect r );
232 void ui_rect_pad( ui_rect rect, ui_px pad[2] );
233 ui_px ui_text_line_width( const char *str );
234 ui_px ui_text_string_height( const char *str );
235 ui_px ui_text_aligned_x( const char *str, ui_rect rect, ui_px scale,
236 enum ui_align align );
237 int ui_clip( ui_rect parent, ui_rect child, ui_rect clipped );
238 int ui_inside_rect( ui_rect rect, ui_px co[2] );
239 int ui_click_down( u32 mask );
240 int ui_clicking( u32 mask );
241 int ui_click_up( u32 mask );
242 void ui_set_mouse_pos( ui_px x, ui_px y );
243 void ui_prerender(void);
244 u32 ui_colour( enum ui_scheme_colour id );
245
246 /* get an appropriately contrasting colour given the base */
247 u32 ui_colourcont( enum ui_scheme_colour id );
248
249 void ui_hex_to_norm( u32 hex, v4f norm );
250 u32 v4f_u32_colour( v4f colour );
251
252 u32 ui_opacity( u32 colour, f32 opacity );
253 void ui_font_face( vg_font_face *ff );
254 u32 ui_ntext( ui_rect rect, const char *str, u32 len, ui_px scale,
255 enum ui_align align, u32 colour );
256 u32 ui_text( ui_rect rect, const char *str, ui_px scale,
257 enum ui_align align, u32 colour );
258 void ui_panel( ui_rect in_rect, ui_rect out_panel );
259 void ui_label( ui_rect rect, const char *text, ui_px size,
260 ui_px gap, ui_rect r );
261 void ui_standard_widget( ui_rect inout_panel, ui_rect out_rect, ui_px count );
262 void ui_info( ui_rect inout_panel, const char *text );
263 void ui_image( ui_rect rect, GLuint image );
264 void ui_defocus_all(void);
265
266 enum ui_button_state ui_button_base( ui_rect rect );
267 enum ui_button_state ui_colourbutton( ui_rect rect,
268 enum ui_scheme_colour colour,
269 enum ui_scheme_colour hover_colour,
270 enum ui_scheme_colour hi_colour );
271 enum ui_button_state ui_colourbutton_text(
272 ui_rect rect, const char *string, ui_px scale,
273 enum ui_scheme_colour colour );
274 enum ui_button_state ui_button_text( ui_rect rect,
275 const char *string, ui_px scale );
276 enum ui_button_state ui_button( ui_rect inout_panel, const char *string );
277
278 void ui_postrender(void);
279
280 int ui_checkbox( ui_rect inout_panel, const char *str_label, i32 *data );
281 void ui_enum( ui_rect inout_panel, const char *str_label,
282 struct ui_enum_opt *options, u32 len, i32 *value );
283 bool ui_slider( ui_rect inout_panel, const char *str_label,
284 f32 min, f32 max, f32 *value, const char *format );
285 void ui_colourpicker( ui_rect inout_panel, const char *str_label, v4f value );
286 int ui_textbox( ui_rect inout_panel, const char *label,
287 char *buf, u32 len, u32 lines, u32 flags,
288 struct ui_textbox_callbacks *callbacks );
289 void ui_tabs( ui_rect inout_panel, ui_rect out_content_panel,
290 const char **titles, u32 count, i32 *page );
291 void ui_start_modal( const char *message, u32 options );
292 void ui_proc_key( SDL_Keysym ev );
293 void ui_proc_utf8( const char *text );
294 void ui_dev_colourview(void);
295
296 void _ui_textbox_move_cursor( int *cursor0, int *cursor1,
297 int dir, int snap_together );
298 int _ui_textbox_delete_char( int direction );
299 void _ui_textbox_put_char( char c );
300 void _ui_textbox_up(void);
301 void _ui_textbox_left(void);
302 void _ui_textbox_left_select(void);
303 void _ui_textbox_down(void);
304 void _ui_textbox_right_select(void);
305 void _ui_textbox_right(void);
306 void _ui_textbox_backspace(void);
307 void _ui_textbox_delete(void);
308 void _ui_textbox_home_select(void);
309 void _ui_textbox_home(void);
310 void _ui_textbox_end_select(void);
311 void _ui_textbox_end(void);
312 void _ui_textbox_select_all(void);
313 void _ui_textbox_cut(void);
314 void _ui_textbox_enter(void);