nandi/jolt-nativepublic Fork 0
e0d90292c3d0c00acad1fb5cdc100d728938759f
Commits
Clone
git clone https://git.rickub.com/nandi/jolt-native.git
git clone ssh://git@rickub.com/nandi/jolt-native.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

vidya_tree.h · 236 lines · 10.0 KBC Blame HistoryRaw
Bring vidya in cfd3e36 nandi 19d ago1/*
2 * Vidya's retained-tree ABI — the reactive half.
3 *
4 * `raylib/include/vidya.h` is push/pop: the caller writes its UI out top to
5 * bottom every frame. That suits a program with a frame loop; it does not suit
6 * a reactive toolkit, which keeps a component tree, diffs it, and emits
7 * create/patch/append/remove against native widgets.
8 *
9 * This header is that widget layer. Nodes are integer handles, mutated by the
10 * calls below; nothing is drawn until `vidya_tree_frame`, which paints the
11 * whole tree at once. Interactions come back as a queue of events the caller
12 * drains and routes to its own handlers — a callback cannot cross this
13 * boundary, so identity does instead.
14 *
15 * The two halves share a window: open it with `vidya_open`, set the mode with
16 * `vidya_set_mode`, and drive `vidya_tree_frame` in place of
17 * `vidya_begin_frame` / `vidya_end_frame`. Do not mix them within one frame.
18 *
19 * Only the Rust/egui backend (`ffi/`) implements this header; the C/raylib
20 * backend implements `vidya.h` alone. Every call stays on the thread that
21 * called `vidya_open`, like the rest of the ABI.
22 */
23#ifndef VIDYA_TREE_H
24#define VIDYA_TREE_H
25
26#include "vidya.h"
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/*
33 * Node handles are positive; 0 is "no node" — a failed allocation, and the
34 * `sibling` argument that means "first position".
35 *
36 * Tags are hiccup names without the colon:
37 *
38 * containers window box hbox vbox page card frame scroll
39 * widgets label title title-2 dim-label button checkbutton entry
40 * separator spacer progress spinner status
41 *
42 * An unrecognized tag is kept and paints as a vertical box, so a caller ahead
43 * of this backend still sees its children.
44 *
45 * Props are string-keyed, in the same names:
46 *
47 * every node sensitive (bool)
48 * box orientation ("horizontal"|"vertical"), spacing, margin
49 * page max-width
50 * scroll orientation ("vertical"|"horizontal"|"both")
51 * text widgets label, or text
52 * button label, kind ("default"|"primary"|"destructive")
53 * checkbutton label, active (bool)
54 * entry text, placeholder, multiline (bool), rows
55 * spacer size
56 * progress value (0..1), label
57 * status label, live (bool)
58 */
59
Fill the slot, and do not wedge on the way out e86c31c nandi 19d ago60/* An `:image` is bounded by `max-width` / `max-height` and, by default, never
61 * drawn larger than its own pixels — enlarging a screenshot to fill a column
62 * makes it worse. `upscale` says otherwise, for a picture whose size the
63 * layout decided rather than the file: a video tile is a slot, and a camera
64 * sending 480 wide into a 900-point slot should fill it.
65 */
66
Bring vidya in cfd3e36 nandi 19d ago67/* The window node, created on first use. Mount everything under it. */
68VIDYA_API int vidya_tree_root(void);
69
70VIDYA_API int vidya_node_new(const char *tag);
71VIDYA_API void vidya_node_free(int node);
72VIDYA_API int vidya_node_exists(int node);
73
74VIDYA_API void vidya_node_set_str(int node, const char *key, const char *value);
75VIDYA_API void vidya_node_set_num(int node, const char *key, double value);
76VIDYA_API void vidya_node_set_bool(int node, const char *key, int value);
77VIDYA_API void vidya_node_clear_props(int node);
78
79/*
80 * Reads answer the empty string / 0 for a prop that is unset or of another
81 * type. The returned pointer belongs to the library and is valid only until
82 * the next string-returning call on this thread — copy it before the next one.
83 */
84VIDYA_API const char *vidya_node_get_str(int node, const char *key);
85VIDYA_API double vidya_node_get_num(int node, const char *key);
86VIDYA_API int vidya_node_get_bool(int node, const char *key);
87
88/*
89 * Reading the structure back. `vidya_node_tag` answers the canonical tag name
90 * ("box" for both hbox and vbox), under the same borrowed-pointer rule as the
91 * prop reads above; `vidya_node_child_at` answers 0 past the end.
92 */
93VIDYA_API const char *vidya_node_tag(int node);
94VIDYA_API int vidya_node_child_count(int node);
95VIDYA_API int vidya_node_child_at(int node, int index);
96
97/*
98 * The subtree at `node` as pretty-printed hiccup — `[:tag {props} children...]`,
99 * one node to a line — for logging, tests, and bug reports. `node` 0 means the
100 * root, so `vidya_tree_dump(0)` is the whole window. Borrowed pointer, under
101 * the same rule as the reads above.
102 *
103 * It answers what the tree *is*, read back from the arena, rather than what a
104 * caller meant to build. Two caveats: `hbox` and `vbox` both dump as `box`,
105 * with the orientation in the props, and handlers are absent because they
106 * never crossed this boundary.
107 */
108VIDYA_API const char *vidya_tree_dump(int node);
109
110VIDYA_API int vidya_node_append(int parent, int child);
111/* Unparents AND frees `child` with everything under it. */
112VIDYA_API void vidya_node_remove(int parent, int child);
113/* Moves `child` after `sibling`; `sibling` 0 means the first position. */
114VIDYA_API int vidya_node_insert_after(int parent, int child, int sibling);
115/* Puts `new_child` where `old_child` was, and frees `old_child`. */
116VIDYA_API int vidya_node_replace(int parent, int old_child, int new_child);
117
118/* Paint the whole tree as one frame. Inert with no window open. */
119VIDYA_API void vidya_tree_frame(void);
120
121/*
122 * Drain interactions. `vidya_tree_poll_event` dequeues one and answers 1 while
123 * there was one; the accessors describe whichever was dequeued last.
124 *
125 * Event names are glimmer's handler props without the `on-`:
126 *
127 * click a button was pressed no payload
128 * toggled a checkbutton changed num is the new state
129 * change an entry's text changed text is the new text
130 * activate Enter was pressed in an entry no payload
131 *
132 * A widget does not own its value: `toggled` and `change` write the new state
133 * back into the node's props as well, so a caller that ignores the event still
134 * sees a working control, and the next prop write is what settles it.
135 */
136VIDYA_API int vidya_tree_poll_event(void);
137VIDYA_API int vidya_tree_event_node(void);
138VIDYA_API const char *vidya_tree_event_name(void);
139VIDYA_API const char *vidya_tree_event_text(void);
140VIDYA_API double vidya_tree_event_num(void);
141
Tell a caller how big the window is 42dabb0 nandi 19d ago142/* The window
143 *
144 * Its size in points — not pixels — because whoever asks is about to lay
145 * something out, and layout is in the units the widgets use. 0 before the
146 * first frame.
147 *
148 * A caller wanting something to be a share of the window rather than a fixed
149 * size needs this: how many of them there are and how much gap goes between
150 * them is the caller's arithmetic, not something one widget can work out from
151 * the space it was handed.
152 *
153 * Reads what egui last saw, so it answers between frames as well as during
154 * one, and follows the window when it is dragged.
155 */
156VIDYA_API float vidya_screen_width(void);
157VIDYA_API float vidya_screen_height(void);
158
Bring vidya in cfd3e36 nandi 19d ago159/* Live frames
160 *
161 * Hand the tree a frame of raw pixels under `key`; any `:image` node whose
162 * `feed` prop names it paints the latest one. Returns 1 when accepted.
163 *
164 * This is what `src` cannot do: a `src` image decodes a file and caches the
165 * texture by its path for the life of the process, which is right for a
166 * picture in a message and useless for a source that makes a new one thirty
167 * times a second. A caller with its own pixels — a camera, a video decoder, a
168 * renderer — pushes them here instead.
169 *
170 * `rgba` is width * height * 4 bytes, row-major, 8 bits a channel,
171 * un-premultiplied. It is copied before the call returns; the caller may reuse
172 * the buffer immediately. A length disagreeing with the dimensions is refused.
173 *
174 * Frames coalesce rather than queue: one arriving before the last was painted
175 * replaces it, so a source faster than the window builds no backlog.
176 *
177 * Like the rest of this ABI, on the window's thread. `vidya_frame_drop`
178 * forgets a feed and releases its texture — without it the last frame of a
179 * source that has stopped keeps painting.
180 */
181VIDYA_API int vidya_frame_rgba(const char *key, int width, int height,
182 const unsigned char *rgba);
183VIDYA_API int vidya_frame_drop(const char *key);
184
185/* Clipboard
186 *
187 * Write the picture on the system clipboard to `path` as a PNG; returns 1 when
188 * there was one and it was written, 0 otherwise (an empty clipboard, text on
189 * it, an unwritable path, or a platform with no image clipboard at all).
190 *
191 * A pasted image arrives through no event — egui carries only clipboard text
192 * into a frame — so this is asked rather than waited for: bind it to whatever
193 * gesture means paste, and read the file it names. Needs no window, and unlike
194 * the rest of this ABI is not tied to the window's thread.
195 */
196VIDYA_API int vidya_clipboard_image_png(const char *path);
197
198/* Open a URL
199 *
200 * Hand `url` to whatever shows web pages here — xdg-open/open on the desktop,
201 * an ACTION_VIEW intent on Android; returns 1 when something took it and 0
202 * otherwise, in which case show the URL and let the reader carry it across.
203 *
204 * Like the clipboard call above it needs no window and no particular thread.
205 */
206VIDYA_API int vidya_open_url(const char *url);
207
Catch up with vidya c90f8af nandi 19d ago208/* Choose a picture
209 *
210 * `vidya_pick_image` asks the platform for its own picture chooser and returns
211 * 1 when one opened. It does not answer with the picture: the reader is in
212 * another screen by then, and may be for a while. Poll `vidya_picked_image`
213 * with the path to put it at — 1 once there is one, and the answer is handed
214 * over only once.
215 *
216 * Android only, and only where the host activity offers the chooser: it is
217 * `void pickImage()` and `String takePickedImage()` on the activity named by
218 * the manifest, which a plain NativeActivity does not have. 0 everywhere else,
219 * which is a caller's cue to browse the filesystem itself.
220 *
221 * Both need no window and no particular thread.
222 */
223VIDYA_API int vidya_pick_image(void);
224VIDYA_API int vidya_picked_image(const char *path);
225
Register vidya_set_title, which the phone cannot call without it 726f7c6 nandi 18d ago226/* The window's title. Declared here because the ABI exports it and the
227 * Android glue has to name every symbol it registers — on the phone the
228 * loader answers for none of them, so a symbol this header omits is one Jolt
229 * cannot call. */
230VIDYA_API void vidya_set_title(const char *title);
231
Bring vidya in cfd3e36 nandi 19d ago232#ifdef __cplusplus
233}
234#endif
235
236#endif /* VIDYA_TREE_H */