PatchworkOS  966e257
A non-POSIX operating system.
Loading...
Searching...
No Matches
element.h
Go to the documentation of this file.
1#ifndef PATCHWORK_ELEMENT_H
2#define PATCHWORK_ELEMENT_H 1
3
4#include "cmd.h"
5#include "drawable.h"
6#include "element_id.h"
7#include "font.h"
8#include "procedure.h"
9#include "rect.h"
10#include "theme.h"
11
12#include <stdbool.h>
13#include <stdint.h>
14#include <sys/proc.h>
15
16#if defined(__cplusplus)
17extern "C"
18{
19#endif
20
21/**
22 * @brief UI Elements.
23 * @defgroup libpatchwork_element UI Elements
24 * @ingroup libpatchwork
25 *
26 * A window is made up of a tree of elements, each element is responsible for drawing a part of the window and handling
27 * events for that part. Elements can have child elements, which are drawn on top of the parent element.
28 *
29 * Each element will on creation, copy the current global theme as its own theme, which can then be modified on a
30 * per-element basis.
31 *
32 * @{
33 */
34
35/**
36 * @brief Element flags type.
37 * @typedef element_flags_t
38 *
39 * We make this a uint64_t instead an an enum to give us more flags for the future.
40 */
42
43#define ELEMENT_NONE 0
44#define ELEMENT_TOGGLE (1 << 0)
45#define ELEMENT_FLAT (1 << 1)
46#define ELEMENT_NO_BEZEL (1 << 2)
47#define ELEMENT_NO_OUTLINE (1 << 3)
48
49/**
50 * @brief Opaque element structure.
51 * @struct element_t
52 */
53typedef struct element element_t;
54
55/**
56 * @brief Element text properties structure.
57 * @struct text_props_t
58 *
59 * To avoid code duplication, we implement a text properties structure that can be used by any element that
60 * needs to render text.
61 */
68
69/**
70 * @brief Element image properties structure.
71 * @struct image_props_t
72 *
73 * To avoid code duplication, we implement an image properties structure that can be used by any element that
74 * needs to render an image.
75 */
82
83/**
84 * @brief Allocate and initialize a new element.
85 *
86 * Will send a fake `EVENT_LIB_INIT` event to the element after creation, followed by a real `EVENT_LIB_REDRAW` event.
87 *
88 * A event being fake just means its sent by directly calling the element procedure, instead of being pushed to the
89 * display's event queue.
90 *
91 * @param parent The parent element.
92 * @param id The element ID.
93 * @param rect The elements rectangle relative to its parent.
94 * @param text The elements text, if the element is for example a button, this will be the button label.
95 * @param flags The element flags.
96 * @param procedure The element procedure.
97 * @param private Pointer to private data for the element.
98 * @return On success, a pointer to the new element. On failure, `NULL` and `errno` is set.
99 */
100element_t* element_new(element_t* parent, element_id_t id, const rect_t* rect, const char* text, element_flags_t flags,
101 procedure_t procedure, void* private);
102
103/**
104 * @brief Deinitialize and free an element and all its children.
105 *
106 * Will send a fake `EVENT_LIB_DEINIT` event to the element before freeing it.
107 *
108 * @param elem The element to free.
109 */
110void element_free(element_t* elem);
111
112/**
113 * @brief Find a child element by its ID.
114 *
115 * Will search recursively through all child elements.
116 *
117 * @param elem The element to search from.
118 * @param id The element ID to search for.
119 * @return A pointer to the found element, or `NULL` if not found.
120 */
122
123/**
124 * @brief Set private data for an element.
125 *
126 * @param elem The element.
127 * @param private Pointer to the private data.
128 */
129void element_set_private(element_t* elem, void* private);
130
131/**
132 * @brief Get private data for an element.
133 *
134 * @param elem The element.
135 * @return Pointer to the private data, or `NULL` if none is set.
136 */
137void* element_get_private(element_t* elem);
138
139/**
140 * @brief Get the ID of an element.
141 *
142 * @param elem The element.
143 * @return The element ID, or `ELEMENT_ID_NONE` if `elem` is `NULL`.
144 */
146
147/**
148 * @brief Move an element to a new rectangle in its parent's coordinate space.
149 *
150 * Will NOT redraw the element, call `element_redraw()` if needed.
151 *
152 * @param elem The element.
153 * @param rect The new rectangle.
154 */
155void element_move(element_t* elem, const rect_t* rect);
156
157/**
158 * @brief Get the rectangle of an element in its parent's coordinate space.
159 *
160 * Equivalent to `RECT_INIT_DIM(x, y, width, height)`.
161 *
162 * @param elem The element.
163 * @return The element rectangle, or a zero-area rectangle if `elem` is `NULL`.
164 */
166
167/**
168 * @brief Get the element's rectangle in local coordinates.
169 *
170 * Equivalent to `RECT_INIT_DIM(0, 0, width, height)`.
171 *
172 * @param elem The element.
173 * @return The content rectangle, or a zero-area rectangle if `elem` is `NULL`.
174 */
176
177/**
178 * @brief Get the rectangle of an element in window coordinates.
179 *
180 * @param elem The element.
181 * @return The element rectangle in window coordinates, or a zero-area rectangle if `elem` is `NULL`.
182 */
184
185/**
186 * @brief Get the top-left point of an element in window coordinates.
187 *
188 * @param elem The element.
189 * @return The top-left point in window coordinates, or (0, 0) if `elem` is `NULL`.
190 */
192
193/**
194 * @brief Convert a rectangle from element coordinates to window coordinates.
195 *
196 * @param elem The element.
197 * @param src The source rectangle in element coordinates.
198 * @return The rectangle in window coordinates, or a zero-area rectangle if `elem` or `src` is `NULL`.
199 */
201
202/**
203 * @brief Convert a point from element coordinates to window coordinates.
204 *
205 * @param elem The element.
206 * @param src The source point in element coordinates.
207 * @return The point in window coordinates, or (0, 0) if `elem` or `src` is `NULL`.
208 */
210
211/**
212 * @brief Convert a rectangle from window coordinates to element coordinates.
213 *
214 * @param elem The element.
215 * @param src The source rectangle in window coordinates.
216 * @return The rectangle in element coordinates, or a zero-area rectangle if `elem` or `src` is `NULL`.
217 */
219
220/**
221 * @brief Convert a point from window coordinates to element coordinates.
222 *
223 * @param elem The element.
224 * @param src The source point in window coordinates.
225 * @return The point in element coordinates, or (0, 0) if `elem` or `src` is `NULL`.
226 */
228
229/**
230 * @brief Get the flags of an element.
231 *
232 * @param elem The element.
233 * @return The element flags, or `ELEMENT_NONE` if `elem` is `NULL`.
234 */
236
237/**
238 * @brief Set the flags of an element.
239 *
240 * @param elem The element.
241 * @param flags The new element flags.
242 */
244
245/**
246 * @brief Get the text of an element.
247 *
248 * @param elem The element.
249 * @return The element text, or `NULL` if `elem` is `NULL`.
250 */
251const char* element_get_text(element_t* elem);
252
253/**
254 * @brief Set the text of an element.
255 *
256 * Will NOT redraw the element, call `element_redraw()` if needed.
257 *
258 * @param elem The element.
259 * @param text The new text.
260 * @return On success, `0`. On failure, `ERR` and `errno` is set.
261 */
262uint64_t element_set_text(element_t* elem, const char* text);
263
264/**
265 * @brief Get the text properties of an element.
266 *
267 * The returned pointer can be used to modify the text properties.
268 *
269 * @param elem The element.
270 * @return Pointer to the text properties, or `NULL` if `elem` is `NULL`.
271 */
273
274/**
275 * @brief Get the image of an element.
276 *
277 * @param elem The element.
278 * @return Pointer to the image, or `NULL` if `elem` is `NULL` or has no image.
279 */
281
282/**
283 * @brief Set the image of an element.
284 *
285 * Will NOT redraw the element, call `element_redraw()` if needed.
286 *
287 * @param elem The element.
288 * @param image Pointer to the new image or `NULL` to remove the image.
289 */
291
292/**
293 * @brief Get the image properties of an element.
294 *
295 * The returned pointer can be used to modify the image properties.
296 *
297 * @param elem The element.
298 * @return Pointer to the image properties, or `NULL` if `elem` is `NULL`.
299 */
301
302/**
303 * @brief Get the theme of an element.
304 *
305 * @param elem The element.
306 * @return Pointer to the theme, or `NULL` if `elem` is `NULL`.
307 */
309
310/**
311 * @brief Begin drawing to an element.
312 *
313 * Note that since this will fill the drawable structure with the element's content rectangle, if the element is for
314 * example moved or resized the drawable will be invalid.
315 *
316 * @param elem The element to draw to.
317 * @param draw Pointer to the drawable structure to initialize.
318 */
319void element_draw_begin(element_t* elem, drawable_t* draw);
320
321/**
322 * @brief End drawing to an element.
323 *
324 * This will invalidate the area of the element that was drawn to and send redraw events to any child elements that
325 * overlap the invalid area.
326 *
327 * @param elem The element that was drawn to.
328 * @param draw Pointer to the drawable structure that was used for drawing.
329 */
330void element_draw_end(element_t* elem, drawable_t* draw);
331
332/**
333 * @brief Redraw an element.
334 *
335 * Will push a `EVENT_LIB_REDRAW` event to the display event queue for the element, meaning the redraw event is not
336 * processed immediately.
337 *
338 * @param elem The element to redraw.
339 * @param shouldPropagate Whether the redraw event should propagate to child elements.
340 */
341void element_redraw(element_t* elem, bool shouldPropagate);
342
343/**
344 * @brief Force an action on an element.
345 *
346 * Will push a `EVENT_LIB_FORCE_ACTION` event to the display event queue for the element, meaning the action event is
347 * not processed immediately.
348 *
349 * @param elem The element.
350 * @param action The action to force.
351 */
353
354/**
355 * @brief Dispatch an event to an element.
356 *
357 * This will call the element's procedure with the given event after some preprocessing.
358 *
359 * Most events will also be propagated to child elements by the element's procedure.
360 *
361 * @param elem The element.
362 * @param event The event to dispatch.
363 * @return The return value of the element's procedure.
364 */
365uint64_t element_dispatch(element_t* elem, const event_t* event);
366
367/**
368 * @brief Emit an event to an element.
369 *
370 * This function will construct an event and dispatch it to the element.
371 *
372 * @param elem The element.
373 * @param type The event type.
374 * @param data Pointer to the event data, can be `NULL` if `size` is `0`.
375 * @param size The size of the event data.
376 * @return On success, `0`. On failure, `ERR` and `errno` is set.
377 */
378uint64_t element_emit(element_t* elem, event_type_t type, const void* data, uint64_t size);
379
380/** @} */
381
382#if defined(__cplusplus)
383}
384#endif
385
386#endif
static fd_t data
Definition dwm.c:21
align_t
Alignment type.
Definition drawable.h:48
image_t * element_get_image(element_t *elem)
Get the image of an element.
text_props_t * element_get_text_props(element_t *elem)
Get the text properties of an element.
Definition element.c:361
void element_set_image(element_t *elem, image_t *image)
Set the image of an element.
Definition element.c:381
void element_set_flags(element_t *elem, element_flags_t flags)
Set the flags of an element.
Definition element.c:323
void element_set_private(element_t *elem, void *private)
Set private data for an element.
Definition element.c:163
element_t * element_find(element_t *elem, element_id_t id)
Find a child element by its ID.
Definition element.c:134
uint64_t element_emit(element_t *elem, event_type_t type, const void *data, uint64_t size)
Emit an event to an element.
Definition element.c:555
theme_t * element_get_theme(element_t *elem)
Get the theme of an element.
Definition element.c:401
image_props_t * element_get_image_props(element_t *elem)
Get the image properties of an element.
point_t element_point_to_window(element_t *elem, const point_t *src)
Convert a point from element coordinates to window coordinates.
Definition element.c:269
rect_t element_window_to_rect(element_t *elem, const rect_t *src)
Convert a rectangle from window coordinates to element coordinates.
Definition element.c:283
uint64_t element_dispatch(element_t *elem, const event_t *event)
Dispatch an event to an element.
Definition element.c:476
void element_draw_end(element_t *elem, drawable_t *draw)
End drawing to an element.
Definition element.c:427
element_t * element_new(element_t *parent, element_id_t id, const rect_t *rect, const char *text, element_flags_t flags, procedure_t procedure, void *private)
Allocate and initialize a new element.
Definition element.c:48
rect_t element_get_content_rect(element_t *elem)
Get the element's rectangle in local coordinates.
Definition element.c:213
uint64_t element_flags_t
Element flags type.
Definition element.h:41
void element_draw_begin(element_t *elem, drawable_t *draw)
Begin drawing to an element.
Definition element.c:411
rect_t element_rect_to_window(element_t *elem, const rect_t *src)
Convert a rectangle from element coordinates to window coordinates.
Definition element.c:253
const char * element_get_text(element_t *elem)
Get the text of an element.
uint64_t element_id_t
Element identifier type.
Definition element_id.h:23
rect_t element_get_window_rect(element_t *elem)
Get the rectangle of an element in window coordinates.
Definition element.c:223
void element_free(element_t *elem)
Deinitialize and free an element and all its children.
Definition element.c:113
point_t element_get_window_point(element_t *elem)
Get the top-left point of an element in window coordinates.
Definition element.c:234
void element_redraw(element_t *elem, bool shouldPropagate)
Redraw an element.
Definition element.c:450
element_id_t element_get_id(element_t *elem)
Get the ID of an element.
Definition element.c:183
uint64_t element_set_text(element_t *elem, const char *text)
Set the text of an element.
Definition element.c:343
rect_t element_get_rect(element_t *elem)
Get the rectangle of an element in its parent's coordinate space.
Definition element.c:203
element_flags_t element_get_flags(element_t *elem)
Get the flags of an element.
point_t element_window_to_point(element_t *elem, const point_t *src)
Convert a point from window coordinates to element coordinates.
Definition element.c:299
void element_move(element_t *elem, const rect_t *rect)
Move an element to a new rectangle in its parent's coordinate space.
Definition element.c:193
void element_force_action(element_t *elem, action_type_t action)
Force an action on an element.
Definition element.c:463
void * element_get_private(element_t *elem)
Get private data for an element.
Definition element.c:173
action_type_t
Action type.
Definition event.h:48
uint16_t event_type_t
Event type.
Definition event.h:72
static const path_flag_t flags[]
Definition path.c:42
uint64_t(* procedure_t)(window_t *, element_t *, const event_t *)
Definition procedure.h:15
static uint64_t procedure(window_t *win, element_t *elem, const event_t *event)
Definition main.c:46
static image_t * image
Definition main.c:5
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
Drawable structure.
Definition drawable.h:35
Opaque element structure.
Definition internal.h:23
Event structure.
Definition event.h:271
Element image properties structure.
Definition element.h:77
point_t srcOffset
Definition element.h:80
align_t xAlign
Definition element.h:78
align_t yAlign
Definition element.h:79
Definition rect.h:13
Element text properties structure.
Definition element.h:63
font_t * font
Definition element.h:66
align_t yAlign
Definition element.h:65
align_t xAlign
Definition element.h:64
Theme structure.
Definition theme.h:71