aboutsummaryrefslogtreecommitdiff
path: root/termkit.h
blob: 36028aa05dac18bcc58d8126b2b5024dddc321e7 (plain)
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// This file is part of libtermkit, a small utility library around
// libtermbox, an alternative to libncurses. It aims to provide a
// convenient and easy to use widget abstraction to build terminal
// based GUIs, in C99.
//
// In principle, termkit only wraps functions provided by termbox,
// but does so while providing state handling and render utilities.
// In termkit, the smallest element is a "node", not a cell. This
// means that the smallest unit is a sentence or visual element.
// A visual element can then either simply be that sentence, or have
// decorations applied to it via `tk_style_t` which is a shared
// style-sheet across an application.
//
// libtermkit is free software, written by Katharina Fey, and licensed
// under the GNU Public License 3.0 or later. See the included license
// reference provided with a copy of this library source code.

#ifndef term_h_INCLUDED
#define term_h_INCLUDED

#include <stdint.h>
#include <bowl.h>

/** 
 * A common stylesheet for termkit applications
 *
 * A stylesheet determines the way that an application looks,
 * beyond setting individual cells to certain fg and bg colours.
 * It supports labels that can be associated with different
 * colour styles (via `tk_sty_color(...)`) or even decorations
 * with `tk_sty_decor(...)` that are applied to an element.
 */
typedef struct {
    uint16_t fg, bg;
    struct bowl *styles;
    struct bowl *decorators;
} tk_style_t;

/** 
 * A decorator element for widgets
 * 
 * A decorator is visible "stuff", that's not directly data related. This
 * could be a colourful frame or shadows. By using characters in the area
 * data, this can be used to also draw UTF-8 compatible characters as
 * outlines.
 * Each decoration element get's colour values from a stylesheet.
 * 
 * See the type constructor for more information.
 */
typedef struct {
    uint32_t ***area; // FIXME: A hack for UTF-8
    tk_style_t *sty;
    char *sty_name;
    // Spans open a container box
    uint16_t ux, uy, lx, ly;
} tk_decor_t;

/** Allocate a new stylesheet */
int tk_sty_init(tk_style_t **, uint16_t fg, uint16_t bg);

/** Add a new color style to the stylesheet */
int tk_sty_add_col(tk_style_t *, char *name, uint16_t fg, uint16_t bg);

/** Add a new dectoration type (TODO: How to express?) */
int tk_sty_add_decor(tk_style_t *, char *name, tk_decor_t *);

/** Get a color from the stylesheet, if it exists */
int tk_sty_color(tk_style_t *, char *name, uint16_t *fg, uint16_t *bg);

/** Get a decorator from the stylesheet, if it exists */
int tk_sty_decor(tk_style_t *, char *name, tk_decor_t **);

/** Free all stylesheet resources */
int tk_sty_free(tk_style_t *);

/** A common termkit orientation descriptor */
enum tk_ori {
    HORIZONTAL,
    VERTICAL,
    DIAGONAL,
    REV_HORIZONTAL,
    REV_VERTICAL,
    REV_DIAGONAL,
};

typedef struct {
    tk_style_t *sty;
    char *sty_name, *decor;
    char *value;
    uint16_t x, y;
    enum tk_ori ori;
    bool clickable;
} tk_widget_t;

/** Initialise a termkit window system */
int tk_init();

/** Draw a termkit widget */
int tk_draw_widget(tk_widget_t *);

/** Simple low-level draw function for termkit elements */
int tk_draw_default(char *str, int x, int y, tk_style_t *sty);

/** Full low-level draw function for termkit elements
 * 
 * If `style_name` or `decor` are set to `NULL` it will
 * assume the default style provided by the tk_style_t
 * sheet and render without decorators.
 * 
 * Missing any other parameter will yield an error.
 */
int tk_draw(tk_style_t *sty, char *str, int x, int y,
            char *style_name, char *decor, enum tk_ori ori);

/** A TermKit menu wrapper */
typedef struct {
    // References the application's stylesheet
    tk_style_t *style;
    // Actual menu styles used
    char *sty_name, *decor;
    // Determines render orientation
    enum tk_ori ori;
    // List of items
    tk_widget_t **items;
    // Number an selection of items
    uint8_t count, select;
    // (x, y) position on screen
    uint16_t x, y;
    // Maximum (width, height) of widget
    uint16_t w, h;
} tk_menu_t;

/** Initialise an empty termkit menu 
 *
 * Note that only HORIZONTAL, VERTICAL, REV_HORIZONTAL and REV_VERTICAL
 * are accepted orientations to this function (no diagonals...).
 * The function will return an error otherwise.
 */
int tk_menu_init(tk_menu_t **, uint16_t x, uint16_t y, 
                 tk_style_t *style, enum tk_ori ori);

/** Set a special style and decoration type for this menu */
int tk_menu_set_style(tk_menu_t *, char *style, char *decor);

/** Set the selected item index */
int tk_menu_set_select(tk_menu_t *, uint8_t select);

/** Get the selected item */
int tk_menu_get_selected(tk_menu_t *, char **select);

/** Add a new item */
int tk_menu_add(tk_menu_t *, char *item);

/** Remove an existing item, compacting following items */
int tk_menu_remove(tk_menu_t *, uint8_t idx);

/** Render the menu via termbox */
int tk_menu_draw(tk_menu_t *);

/** Free all resources */
int tk_menu_free(tk_menu_t *);

#endif // term_h_INCLUDED