1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
#pragma once
#include <ui.h>
#include <cstring.h>
#include <list.h>
#include <stdbool.h>
DEF_LIST(Widget, uiWidget*)
/// Base widget type.
typedef struct uiWidget {
uiWidgetType type;
uiRect rect;
Widget_list children;
} uiWidget;
typedef struct uiButton {
uiWidget widget;
string text;
} uiButton;
typedef struct uiFrame {
uiWidget widget;
} uiFrame;
typedef struct uiLabel {
uiWidget widget;
string text;
} uiLabel;
typedef struct uiScrollbar {
int width;
int height; // Total height: handle plus scrollable area.
int handle_height; // Height of the scroll handle.
int handle_y; // Starting y-coordinate of the handle.
} uiScrollbar;
typedef struct uiCell {
string text;
} uiCell;
typedef struct uiTable {
uiWidget widget;
int rows;
int cols;
int height; // Height in pixels.
int* widths; // Width, in pixels, for each column.
uiCell* header; // If non-null, row of 'cols' header cells.
uiCell** cells; // Array of 'rows' rows, each of 'cols' cells.
int offset; // Offset into the rows of the table. Units: rows.
int num_visible_rows; // The number of rows that are visible at once.
uiScrollbar scrollbar;
struct {
bool vertical_overflow : 1; // True if contents overflow vertically.
} flags;
} uiTable;
void DestroyWidget(uiWidget** ppWidget);
/// Set the scrollbar handle's y-coordinate, which is clipped to the scrollbar's
/// rectangle.
///
/// Return the handle's y-coordinate after clipping.
int ScrollbarScroll(uiScrollbar*, int y);
const uiCell* TableGetCell(const uiTable*, int row, int col);
uiCell* TableGetCellMut(uiTable*, int row, int col);
uiCell** TableGetLastRow(uiTable*);
void SyncScrollbarToTable(uiTable*);
void SyncTableToScrollbar(uiTable*);
static inline int Min(int a, int b) { return a < b ? a : b; }
static inline int Max(int a, int b) { return a > b ? a : b; }
static inline void* uiAlloc(size_t count, size_t size) {
void* mem = calloc(count, size);
ASSERT(mem);
return mem;
}
#define UI_NEW(TYPE) (TYPE*)uiAlloc(1, sizeof(TYPE))
|