xbintsc 0.3.14 → 0.3.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -22
- package/README.zh-CN.md +20 -19
- package/bin/xbintsc.js +1 -2
- package/dist/src/cli/main.js +8 -5
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/codegen/generator/state.js +8 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/tables.d.ts +5 -6
- package/dist/src/codegen/generator/tables.js +13 -6
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/driver/bundler/graph.d.ts +8 -0
- package/dist/src/driver/bundler/graph.js +85 -0
- package/dist/src/driver/bundler/graph.js.map +1 -0
- package/dist/src/driver/bundler/merge.d.ts +11 -0
- package/dist/src/driver/bundler/merge.js +288 -0
- package/dist/src/driver/bundler/merge.js.map +1 -0
- package/dist/src/driver/bundler/resolve.d.ts +12 -0
- package/dist/src/driver/bundler/resolve.js +246 -0
- package/dist/src/driver/bundler/resolve.js.map +1 -0
- package/dist/src/driver/bundler/symbols.d.ts +15 -0
- package/dist/src/driver/bundler/symbols.js +51 -0
- package/dist/src/driver/bundler/symbols.js.map +1 -0
- package/dist/src/driver/bundler/types.d.ts +36 -0
- package/dist/src/driver/bundler/types.js +5 -0
- package/dist/src/driver/bundler/types.js.map +1 -0
- package/dist/src/driver/index.d.ts +1 -2
- package/dist/src/driver/index.js +1 -2
- package/dist/src/driver/index.js.map +1 -1
- package/dist/src/driver/modules.d.ts +9 -16
- package/dist/src/driver/modules.js +8 -644
- package/dist/src/driver/modules.js.map +1 -1
- package/dist/src/driver/paths.d.ts +0 -9
- package/dist/src/driver/paths.js +0 -31
- package/dist/src/driver/paths.js.map +1 -1
- package/dist/src/driver/toolchain-provider.d.ts +10 -10
- package/dist/src/driver/toolchain-provider.js +9 -38
- package/dist/src/driver/toolchain-provider.js.map +1 -1
- package/dist/src/driver/toolchain.js +8 -2
- package/dist/src/driver/toolchain.js.map +1 -1
- package/dist/src/extensions/catalog.js +2 -1
- package/dist/src/extensions/catalog.js.map +1 -1
- package/dist/src/extensions/gui/index.d.ts +24 -0
- package/dist/src/extensions/gui/index.js +101 -0
- package/dist/src/extensions/gui/index.js.map +1 -0
- package/dist/src/extensions/native.d.ts +2 -3
- package/dist/src/extensions/native.js +2 -3
- package/dist/src/extensions/native.js.map +1 -1
- package/dist/tests/driver/paths.test.js +1 -9
- package/dist/tests/driver/paths.test.js.map +1 -1
- package/dist/tests/driver/toolchain-provider.test.js +12 -79
- package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
- package/dist/tests/e2e/compile-basics.test.d.ts +4 -0
- package/dist/tests/e2e/compile-basics.test.js +134 -0
- package/dist/tests/e2e/compile-basics.test.js.map +1 -0
- package/dist/tests/e2e/compile-builtins.test.d.ts +4 -0
- package/dist/tests/e2e/compile-builtins.test.js +191 -0
- package/dist/tests/e2e/compile-builtins.test.js.map +1 -0
- package/dist/tests/e2e/compile-control-flow.test.d.ts +4 -0
- package/dist/tests/e2e/compile-control-flow.test.js +190 -0
- package/dist/tests/e2e/compile-control-flow.test.js.map +1 -0
- package/dist/tests/e2e/compile-modules.test.d.ts +4 -0
- package/dist/tests/e2e/compile-modules.test.js +48 -0
- package/dist/tests/e2e/compile-modules.test.js.map +1 -0
- package/dist/tests/e2e/compile-objects-classes.test.d.ts +4 -0
- package/dist/tests/e2e/compile-objects-classes.test.js +362 -0
- package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -0
- package/dist/tests/e2e/differential-helpers.d.ts +12 -0
- package/dist/tests/e2e/differential-helpers.js +16 -0
- package/dist/tests/e2e/differential-helpers.js.map +1 -0
- package/dist/tests/e2e/differential-language.test.d.ts +4 -0
- package/dist/tests/e2e/{differential.test.js → differential-language.test.js} +5 -287
- package/dist/tests/e2e/differential-language.test.js.map +1 -0
- package/dist/tests/e2e/differential-symbols.test.d.ts +4 -0
- package/dist/tests/e2e/differential-symbols.test.js +92 -0
- package/dist/tests/e2e/differential-symbols.test.js.map +1 -0
- package/dist/tests/e2e/differential-values.test.d.ts +4 -0
- package/dist/tests/e2e/differential-values.test.js +197 -0
- package/dist/tests/e2e/differential-values.test.js.map +1 -0
- package/dist/tests/e2e/gui.test.d.ts +12 -0
- package/dist/tests/e2e/gui.test.js +493 -0
- package/dist/tests/e2e/gui.test.js.map +1 -0
- package/dist/tests/e2e/native-extensions.test.d.ts +4 -5
- package/dist/tests/e2e/native-extensions.test.js +6 -7
- package/dist/tests/e2e/native-extensions.test.js.map +1 -1
- package/dist/tests/e2e/runtime-coverage-buffer.test.d.ts +4 -0
- package/dist/tests/e2e/runtime-coverage-buffer.test.js +97 -0
- package/dist/tests/e2e/runtime-coverage-buffer.test.js.map +1 -0
- package/dist/tests/e2e/runtime-coverage-globals.test.d.ts +4 -0
- package/dist/tests/e2e/runtime-coverage-globals.test.js +149 -0
- package/dist/tests/e2e/runtime-coverage-globals.test.js.map +1 -0
- package/dist/tests/e2e/runtime-coverage-node-modules.test.d.ts +4 -0
- package/dist/tests/e2e/runtime-coverage-node-modules.test.js +177 -0
- package/dist/tests/e2e/runtime-coverage-node-modules.test.js.map +1 -0
- package/dist/tests/e2e/runtime-coverage-streams.test.d.ts +4 -0
- package/dist/tests/e2e/runtime-coverage-streams.test.js +161 -0
- package/dist/tests/e2e/runtime-coverage-streams.test.js.map +1 -0
- package/dist/tests/e2e/runtime-coverage-system.test.d.ts +4 -0
- package/dist/tests/e2e/runtime-coverage-system.test.js +91 -0
- package/dist/tests/e2e/runtime-coverage-system.test.js.map +1 -0
- package/dist/tests/e2e/timers.test.d.ts +7 -0
- package/dist/tests/e2e/timers.test.js +63 -0
- package/dist/tests/e2e/timers.test.js.map +1 -0
- package/package.json +2 -2
- package/runtime/ext_gui/css.cpp +743 -0
- package/runtime/ext_gui/css.h +98 -0
- package/runtime/ext_gui/document.cpp +264 -0
- package/runtime/ext_gui/document.h +89 -0
- package/runtime/ext_gui/dom.cpp +472 -0
- package/runtime/ext_gui/dom.h +71 -0
- package/runtime/ext_gui/gui.cpp +457 -0
- package/runtime/ext_gui/gui_engine.h +81 -0
- package/runtime/ext_gui/image.cpp +125 -0
- package/runtime/ext_gui/image.h +42 -0
- package/runtime/ext_gui/layout.cpp +748 -0
- package/runtime/ext_gui/layout.h +93 -0
- package/runtime/ext_gui/paint.cpp +137 -0
- package/runtime/ext_gui/paint.h +75 -0
- package/runtime/ext_gui/renderer.cpp +959 -0
- package/runtime/ext_gui/renderer.h +68 -0
- package/runtime/ext_gui/stb_image.h +7988 -0
- package/runtime/ext_gui/style.cpp +771 -0
- package/runtime/ext_gui/style.h +117 -0
- package/runtime/ext_gui/text.cpp +378 -0
- package/runtime/ext_gui/text.h +78 -0
- package/runtime/ext_gui/window.cpp +405 -0
- package/runtime/ext_node/fs/fs_common.h +13 -527
- package/runtime/ext_node/fs/meta_ops.c +3 -3
- package/runtime/ext_node/fs/parts/buffer-bridge.inc +6 -0
- package/runtime/ext_node/fs/parts/builtins.inc +69 -0
- package/runtime/ext_node/fs/parts/dir.inc +47 -0
- package/runtime/ext_node/fs/parts/encoding.inc +186 -0
- package/runtime/ext_node/fs/parts/errors.inc +66 -0
- package/runtime/ext_node/fs/parts/flags.inc +39 -0
- package/runtime/ext_node/fs/parts/platform.inc +86 -0
- package/runtime/ext_node/fs/parts/promisify.inc +15 -0
- package/runtime/ext_node/fs/parts/time.inc +9 -0
- package/runtime/rt.h +36 -4
- package/runtime/rt_internal.h +10 -23
- package/runtime/xt_builtins.c +4 -0
- package/runtime/xt_containers/access.inc +168 -0
- package/runtime/xt_containers/arrays.inc +108 -0
- package/runtime/xt_containers/boxes.inc +11 -0
- package/runtime/xt_containers/objects.inc +326 -0
- package/runtime/xt_containers.c +8 -618
- package/runtime/xt_ext.h +0 -1
- package/runtime/xt_io/base64.inc +87 -0
- package/runtime/xt_io/console.inc +119 -0
- package/runtime/xt_io/exception.inc +142 -0
- package/runtime/xt_io/inspect.inc +212 -0
- package/runtime/xt_io.c +11 -556
- package/runtime/xt_loop.c +262 -24
- package/runtime/xt_regex/api.inc +58 -0
- package/runtime/xt_regex/helpers.inc +68 -0
- package/runtime/xt_regex/matcher.inc +248 -0
- package/runtime/xt_regex/parser.inc +236 -0
- package/runtime/xt_regex/types.inc +58 -0
- package/runtime/xt_regex.h +9 -672
- package/runtime/xt_stdlib2/helpers.inc +2 -4
- package/runtime/xt_values/arithmetic.inc +150 -0
- package/runtime/xt_values/comparison.inc +112 -0
- package/runtime/xt_values/constructors.inc +41 -0
- package/runtime/xt_values/conversions.inc +115 -0
- package/runtime/xt_values/number-format.inc +180 -0
- package/runtime/xt_values/strings.inc +22 -0
- package/runtime/xt_values.c +10 -626
- package/scripts/build-gui.ts +317 -0
- package/scripts/build-runtime.ts +7 -8
- package/scripts/coverage-runtime.ts +4 -4
- package/scripts/package-release.ts +12 -84
- package/src/cli/main.ts +8 -4
- package/src/codegen/generator/state.ts +8 -0
- package/src/codegen/generator/tables.ts +13 -6
- package/src/driver/bundler/graph.ts +95 -0
- package/src/driver/bundler/merge.ts +312 -0
- package/src/driver/bundler/resolve.ts +240 -0
- package/src/driver/bundler/symbols.ts +55 -0
- package/src/driver/bundler/types.ts +37 -0
- package/src/driver/index.ts +1 -9
- package/src/driver/modules.ts +9 -693
- package/src/driver/paths.ts +0 -31
- package/src/driver/toolchain-provider.ts +12 -45
- package/src/driver/toolchain.ts +7 -2
- package/src/extensions/catalog.ts +2 -1
- package/src/extensions/gui/index.ts +107 -0
- package/src/extensions/native.ts +2 -3
- package/dist/src/driver/toolchain-download.d.ts +0 -50
- package/dist/src/driver/toolchain-download.js +0 -102
- package/dist/src/driver/toolchain-download.js.map +0 -1
- package/dist/tests/driver/toolchain-download.test.d.ts +0 -1
- package/dist/tests/driver/toolchain-download.test.js +0 -53
- package/dist/tests/driver/toolchain-download.test.js.map +0 -1
- package/dist/tests/e2e/compile.test.d.ts +0 -8
- package/dist/tests/e2e/compile.test.js +0 -893
- package/dist/tests/e2e/compile.test.js.map +0 -1
- package/dist/tests/e2e/differential.test.d.ts +0 -7
- package/dist/tests/e2e/differential.test.js.map +0 -1
- package/dist/tests/e2e/runtime-coverage.test.d.ts +0 -11
- package/dist/tests/e2e/runtime-coverage.test.js +0 -646
- package/dist/tests/e2e/runtime-coverage.test.js.map +0 -1
- package/scripts/fetch-toolchain.ts +0 -101
- package/src/driver/toolchain-download.ts +0 -135
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc GUI engine — window methods.
|
|
3
|
+
*
|
|
4
|
+
* Every window returned by `createWindow` is a plain runtime object with the
|
|
5
|
+
* engine's prototype. Methods use the compiled-function ABI
|
|
6
|
+
* `xt_value fn(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv)`
|
|
7
|
+
* and are wrapped into callable values with `xt_closure_new`, exactly like the
|
|
8
|
+
* Node extension's objects.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#include "gui_engine.h"
|
|
12
|
+
|
|
13
|
+
#include "paint.h"
|
|
14
|
+
#include "text.h"
|
|
15
|
+
|
|
16
|
+
static xt_value g_window_proto = XT_UNDEFINED;
|
|
17
|
+
|
|
18
|
+
/* -- methods -------------------------------------------------------------- */
|
|
19
|
+
|
|
20
|
+
static xt_value win_set_title(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
21
|
+
(void)env;
|
|
22
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
23
|
+
if (win != NULL && win->window != NULL && argc >= 1) {
|
|
24
|
+
const char *title = xt_string_data(xt_to_string(xt_arg(argc, argv, 0)));
|
|
25
|
+
SDL_SetWindowTitle(win->window, title);
|
|
26
|
+
}
|
|
27
|
+
return XT_UNDEFINED;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static xt_value win_set_size(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
31
|
+
(void)env;
|
|
32
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
33
|
+
if (win != NULL && win->window != NULL && argc >= 2) {
|
|
34
|
+
SDL_SetWindowSize(win->window, (int)xt_to_number(xt_arg(argc, argv, 0)),
|
|
35
|
+
(int)xt_to_number(xt_arg(argc, argv, 1)));
|
|
36
|
+
}
|
|
37
|
+
return XT_UNDEFINED;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static xt_value win_load_html(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
41
|
+
(void)env;
|
|
42
|
+
std::string html;
|
|
43
|
+
if (argc >= 1) {
|
|
44
|
+
xt_value text = xt_to_string(xt_arg(argc, argv, 0));
|
|
45
|
+
const char *data = xt_string_data(text);
|
|
46
|
+
if (data != nullptr) html = data;
|
|
47
|
+
}
|
|
48
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
49
|
+
if (win != nullptr) {
|
|
50
|
+
win->html = html;
|
|
51
|
+
win->document = std::make_unique<xtgui::XtDocument>();
|
|
52
|
+
float width = 0;
|
|
53
|
+
float height = 0;
|
|
54
|
+
xt_gui_window_viewport(win, &width, &height);
|
|
55
|
+
win->document->load(html, width, height);
|
|
56
|
+
win->geometry.dirty = 1;
|
|
57
|
+
}
|
|
58
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_html"), xt_string_from_cstr(html.c_str()));
|
|
59
|
+
/* Painting the document is milestone M3b+; the parsed tree and computed
|
|
60
|
+
* styles are available now (see `computedStyle`). */
|
|
61
|
+
xt_gui_emit(win, "load");
|
|
62
|
+
return XT_UNDEFINED;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static xt_value win_get_html(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
66
|
+
(void)env;
|
|
67
|
+
(void)argc;
|
|
68
|
+
(void)argv;
|
|
69
|
+
return xt_object_get_cstr(self, "__xt_gui_html");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Diagnostic/test hook: computed value of `property` for the first match of
|
|
73
|
+
* `selector`, or an empty string. */
|
|
74
|
+
static xt_value win_computed_style(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
75
|
+
(void)env;
|
|
76
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
77
|
+
if (win == nullptr || win->document == nullptr || argc < 2) return xt_string_from_cstr("");
|
|
78
|
+
xt_value selectorValue = xt_to_string(xt_arg(argc, argv, 0));
|
|
79
|
+
xt_value propertyValue = xt_to_string(xt_arg(argc, argv, 1));
|
|
80
|
+
const char *selector = xt_string_data(selectorValue);
|
|
81
|
+
const char *property = xt_string_data(propertyValue);
|
|
82
|
+
if (selector == nullptr || property == nullptr) return xt_string_from_cstr("");
|
|
83
|
+
const xtgui::Node *node = win->document->querySelector(selector);
|
|
84
|
+
if (node == nullptr) return xt_string_from_cstr("");
|
|
85
|
+
const xtgui::XtStyle *style = win->document->styleOf(node);
|
|
86
|
+
if (style == nullptr) return xt_string_from_cstr("");
|
|
87
|
+
std::string text = xtgui::xt_style_property_to_string(*style, property);
|
|
88
|
+
return xt_string_from_cstr(text.c_str());
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Diagnostic/test hook: serialized DOM. */
|
|
92
|
+
static xt_value win_document_tree(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
93
|
+
(void)env;
|
|
94
|
+
(void)argc;
|
|
95
|
+
(void)argv;
|
|
96
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
97
|
+
if (win == nullptr || win->document == nullptr) return xt_string_from_cstr("");
|
|
98
|
+
std::string text = win->document->toDebugString();
|
|
99
|
+
return xt_string_from_cstr(text.c_str());
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Diagnostic/test hook: number of elements matching a selector. */
|
|
103
|
+
static xt_value win_query_count(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
104
|
+
(void)env;
|
|
105
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
106
|
+
if (win == nullptr || win->document == nullptr || argc < 1) return xt_number(0);
|
|
107
|
+
xt_value selectorValue = xt_to_string(xt_arg(argc, argv, 0));
|
|
108
|
+
const char *selector = xt_string_data(selectorValue);
|
|
109
|
+
if (selector == nullptr) return xt_number(0);
|
|
110
|
+
return xt_number((double)win->document->querySelectorAll(selector).size());
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Diagnostic/test hook: laid-out border box of the first match of `selector`,
|
|
114
|
+
* as `{ x, y, width, height }` (viewport-relative), or `undefined`. */
|
|
115
|
+
static xt_value win_get_bounding_rect(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
116
|
+
(void)env;
|
|
117
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
118
|
+
if (win == nullptr || win->document == nullptr || argc < 1) return XT_UNDEFINED;
|
|
119
|
+
xt_value selectorValue = xt_to_string(xt_arg(argc, argv, 0));
|
|
120
|
+
const char *selector = xt_string_data(selectorValue);
|
|
121
|
+
if (selector == nullptr) return XT_UNDEFINED;
|
|
122
|
+
const xtgui::Node *node = win->document->querySelector(selector);
|
|
123
|
+
if (node == nullptr) return XT_UNDEFINED;
|
|
124
|
+
const xtgui::LayoutBox *box = win->document->boxOf(node);
|
|
125
|
+
if (box == nullptr) return XT_UNDEFINED;
|
|
126
|
+
xt_value object = xt_object_new();
|
|
127
|
+
xt_object_set(object, xt_string_from_cstr("x"), xt_number(box->x));
|
|
128
|
+
xt_object_set(object, xt_string_from_cstr("y"), xt_number(box->y));
|
|
129
|
+
xt_object_set(object, xt_string_from_cstr("width"), xt_number(box->width));
|
|
130
|
+
xt_object_set(object, xt_string_from_cstr("height"), xt_number(box->height));
|
|
131
|
+
return object;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Diagnostic/test hook: serialized layout box tree. */
|
|
135
|
+
static xt_value win_layout_tree(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
136
|
+
(void)env;
|
|
137
|
+
(void)argc;
|
|
138
|
+
(void)argv;
|
|
139
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
140
|
+
if (win == nullptr || win->document == nullptr) return xt_string_from_cstr("");
|
|
141
|
+
std::string text = win->document->layout().dump();
|
|
142
|
+
return xt_string_from_cstr(text.c_str());
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static xt_value win_set_background(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
146
|
+
(void)env;
|
|
147
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
148
|
+
if (win != NULL && argc >= 1) {
|
|
149
|
+
xt_value text = xt_to_string(xt_arg(argc, argv, 0));
|
|
150
|
+
const char *data = xt_string_data(text);
|
|
151
|
+
if (data != nullptr) {
|
|
152
|
+
xtgui::Color color = xtgui::xt_css_parse_color(data);
|
|
153
|
+
if (color.valid) {
|
|
154
|
+
win->background[0] = color.r;
|
|
155
|
+
win->background[1] = color.g;
|
|
156
|
+
win->background[2] = color.b;
|
|
157
|
+
win->background[3] = color.a;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_background"), text);
|
|
161
|
+
}
|
|
162
|
+
return XT_UNDEFINED;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Diagnostic/test hook: the display list built from the current layout. */
|
|
166
|
+
static xt_value win_paint_list(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
167
|
+
(void)env;
|
|
168
|
+
(void)argc;
|
|
169
|
+
(void)argv;
|
|
170
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
171
|
+
if (win == nullptr || win->document == nullptr) return xt_string_from_cstr("");
|
|
172
|
+
xtgui::DisplayList list;
|
|
173
|
+
xtgui::xt_paint_build(win->document->layout().root(), list);
|
|
174
|
+
std::string text = list.dump();
|
|
175
|
+
return xt_string_from_cstr(text.c_str());
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Diagnostic/test hook: number of shapes in the display list. */
|
|
179
|
+
static xt_value win_paint_count(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
180
|
+
(void)env;
|
|
181
|
+
(void)argc;
|
|
182
|
+
(void)argv;
|
|
183
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
184
|
+
if (win == nullptr || win->document == nullptr) return xt_number(0);
|
|
185
|
+
xtgui::DisplayList list;
|
|
186
|
+
xtgui::xt_paint_build(win->document->layout().root(), list);
|
|
187
|
+
return xt_number((double)list.rects.size());
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Diagnostic/test hook: advance the CSS transition clock by `ms`. */
|
|
191
|
+
static xt_value win_advance(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
192
|
+
(void)env;
|
|
193
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
194
|
+
if (win == nullptr || win->document == nullptr) return XT_UNDEFINED;
|
|
195
|
+
double ms = argc > 0 ? xt_to_number(xt_arg(argc, argv, 0)) : 0.0;
|
|
196
|
+
if (win->document->advance(ms)) win->geometry.dirty = 1;
|
|
197
|
+
return XT_UNDEFINED;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Build a `FontSpec` from trailing method arguments: [text], size, family. */
|
|
201
|
+
static xtgui::FontSpec xt_gui_font_spec(int32_t argc, xt_value *argv, int sizeIndex, int familyIndex) {
|
|
202
|
+
xtgui::FontSpec spec;
|
|
203
|
+
if (argc > sizeIndex && XT_IS_NUMBER(xt_arg(argc, argv, sizeIndex))) {
|
|
204
|
+
double size = xt_to_number(xt_arg(argc, argv, sizeIndex));
|
|
205
|
+
if (size > 0) spec.pixel_size = (float)size;
|
|
206
|
+
}
|
|
207
|
+
if (argc > familyIndex && XT_IS_STRING(xt_arg(argc, argv, familyIndex))) {
|
|
208
|
+
const char *family = xt_string_data(xt_arg(argc, argv, familyIndex));
|
|
209
|
+
if (family != nullptr) spec.family = family;
|
|
210
|
+
}
|
|
211
|
+
return spec;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** Diagnostic/test hook: shaped width of `text` at `fontSize` (optional) in
|
|
215
|
+
* the given family (optional). */
|
|
216
|
+
static xt_value win_measure_text(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
217
|
+
(void)self;
|
|
218
|
+
(void)env;
|
|
219
|
+
std::string text;
|
|
220
|
+
if (argc >= 1) {
|
|
221
|
+
xt_value value = xt_to_string(xt_arg(argc, argv, 0));
|
|
222
|
+
const char *data = xt_string_data(value);
|
|
223
|
+
if (data != nullptr) text = data;
|
|
224
|
+
}
|
|
225
|
+
xtgui::FontSpec spec = xt_gui_font_spec(argc, argv, 1, 2);
|
|
226
|
+
return xt_number((double)xtgui::xt_text_measure_width(text, spec));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** Diagnostic/test hook: vertical metrics at `fontSize` (optional). */
|
|
230
|
+
static xt_value win_font_metrics(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
231
|
+
(void)self;
|
|
232
|
+
(void)env;
|
|
233
|
+
xtgui::FontSpec spec = xt_gui_font_spec(argc, argv, 0, 1);
|
|
234
|
+
float ascent = 0;
|
|
235
|
+
float descent = 0;
|
|
236
|
+
float lineHeight = 0;
|
|
237
|
+
xtgui::xt_text_metrics(spec, &ascent, &descent, &lineHeight);
|
|
238
|
+
xt_value object = xt_object_new();
|
|
239
|
+
xt_object_set(object, xt_string_from_cstr("ascent"), xt_number(ascent));
|
|
240
|
+
xt_object_set(object, xt_string_from_cstr("descent"), xt_number(descent));
|
|
241
|
+
xt_object_set(object, xt_string_from_cstr("lineHeight"), xt_number(lineHeight));
|
|
242
|
+
xt_object_set(object, xt_string_from_cstr("ready"), xtgui::xt_text_ready() ? XT_TRUE : XT_FALSE);
|
|
243
|
+
return object;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
static xt_value win_close(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
247
|
+
(void)env;
|
|
248
|
+
(void)argc;
|
|
249
|
+
(void)argv;
|
|
250
|
+
xt_gui_quit_window(xt_gui_window_from_this(self));
|
|
251
|
+
return XT_UNDEFINED;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
static xt_value win_is_open(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
255
|
+
(void)env;
|
|
256
|
+
(void)argc;
|
|
257
|
+
(void)argv;
|
|
258
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
259
|
+
return (win != NULL && win->open) ? XT_TRUE : XT_FALSE;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
static xt_value win_on(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
263
|
+
(void)env;
|
|
264
|
+
if (argc >= 2) {
|
|
265
|
+
xt_value name = xt_to_string(xt_arg(argc, argv, 0));
|
|
266
|
+
xt_value fn = xt_arg(argc, argv, 1);
|
|
267
|
+
if (XT_IS_FUNCTION(fn)) {
|
|
268
|
+
xt_value listeners = xt_object_get_cstr(self, "__xt_gui_events");
|
|
269
|
+
if (!XT_IS_OBJECT(listeners)) {
|
|
270
|
+
listeners = xt_object_new();
|
|
271
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_events"), listeners);
|
|
272
|
+
}
|
|
273
|
+
xt_value array = xt_object_get(listeners, name);
|
|
274
|
+
if (!XT_IS_ARRAY(array)) {
|
|
275
|
+
array = xt_array_new(0, NULL);
|
|
276
|
+
xt_object_set(listeners, name, array);
|
|
277
|
+
}
|
|
278
|
+
xt_array_push(array, fn);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return self;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
static xt_value win_off(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
285
|
+
(void)env;
|
|
286
|
+
if (argc >= 2) {
|
|
287
|
+
xt_value listeners = xt_object_get_cstr(self, "__xt_gui_events");
|
|
288
|
+
if (XT_IS_OBJECT(listeners)) {
|
|
289
|
+
xt_value name = xt_to_string(xt_arg(argc, argv, 0));
|
|
290
|
+
xt_value fn = xt_arg(argc, argv, 1);
|
|
291
|
+
xt_value array = xt_object_get(listeners, name);
|
|
292
|
+
if (XT_IS_ARRAY(array)) {
|
|
293
|
+
xt_value kept = xt_array_new(0, NULL);
|
|
294
|
+
int32_t count = (int32_t)xt_to_number(xt_array_length(array));
|
|
295
|
+
for (int32_t i = 0; i < count; i++) {
|
|
296
|
+
xt_value candidate = xt_array_get(array, xt_number((double)i));
|
|
297
|
+
if (candidate != fn) xt_array_push(kept, candidate);
|
|
298
|
+
}
|
|
299
|
+
xt_object_set(listeners, name, kept);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return self;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/* -- input diagnostics ---------------------------------------------------- */
|
|
307
|
+
|
|
308
|
+
static double xt_gui_number_or(xt_value value, double fallback) {
|
|
309
|
+
return XT_IS_NUMBER(value) ? xt_to_number(value) : fallback;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** Test/debug hook: CSS-like descriptor of the deepest element at (x, y). */
|
|
313
|
+
static xt_value win_hit_test(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
314
|
+
(void)env;
|
|
315
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
316
|
+
if (win == nullptr || win->document == nullptr || argc < 2) return xt_string_from_cstr("");
|
|
317
|
+
float x = (float)xt_to_number(xt_arg(argc, argv, 0));
|
|
318
|
+
float y = (float)xt_to_number(xt_arg(argc, argv, 1));
|
|
319
|
+
std::string target = xt_gui_hit_test(win, x, y);
|
|
320
|
+
return xt_string_from_cstr(target.c_str());
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** Test/debug hook: synthesise an input event and deliver it to handlers.
|
|
324
|
+
* `win.sendEvent("click", { x, y, button, clicks })`,
|
|
325
|
+
* `win.sendEvent("wheel", { x, y, deltaX, deltaY })` or
|
|
326
|
+
* `win.sendEvent("keydown", { key, code })`. */
|
|
327
|
+
static xt_value win_send_event(xt_value self, xt_value env, int32_t argc, xt_value *argv) {
|
|
328
|
+
(void)env;
|
|
329
|
+
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
330
|
+
if (win == nullptr || argc < 1) return XT_FALSE;
|
|
331
|
+
const char *type = xt_string_data(xt_to_string(xt_arg(argc, argv, 0)));
|
|
332
|
+
if (type == nullptr) return XT_FALSE;
|
|
333
|
+
xt_value options = xt_arg(argc, argv, 1);
|
|
334
|
+
double x = 0;
|
|
335
|
+
double y = 0;
|
|
336
|
+
if (XT_IS_OBJECT(options)) {
|
|
337
|
+
x = xt_gui_number_or(xt_object_get_cstr(options, "x"), 0);
|
|
338
|
+
y = xt_gui_number_or(xt_object_get_cstr(options, "y"), 0);
|
|
339
|
+
}
|
|
340
|
+
std::string name(type);
|
|
341
|
+
if (name == "wheel") {
|
|
342
|
+
double delta_x = 0;
|
|
343
|
+
double delta_y = 0;
|
|
344
|
+
if (XT_IS_OBJECT(options)) {
|
|
345
|
+
delta_x = xt_gui_number_or(xt_object_get_cstr(options, "deltaX"), 0);
|
|
346
|
+
delta_y = xt_gui_number_or(xt_object_get_cstr(options, "deltaY"), 0);
|
|
347
|
+
}
|
|
348
|
+
xt_gui_dispatch_wheel(win, (float)x, (float)y, (float)delta_x, (float)delta_y);
|
|
349
|
+
return XT_TRUE;
|
|
350
|
+
}
|
|
351
|
+
if (name == "keydown" || name == "keyup") {
|
|
352
|
+
const char *key = "";
|
|
353
|
+
const char *code = "";
|
|
354
|
+
if (XT_IS_OBJECT(options)) {
|
|
355
|
+
xt_value key_value = xt_object_get_cstr(options, "key");
|
|
356
|
+
xt_value code_value = xt_object_get_cstr(options, "code");
|
|
357
|
+
if (XT_IS_STRING(key_value)) key = xt_string_data(key_value);
|
|
358
|
+
if (XT_IS_STRING(code_value)) code = xt_string_data(code_value);
|
|
359
|
+
}
|
|
360
|
+
xt_gui_dispatch_key(win, type, key, code);
|
|
361
|
+
return XT_TRUE;
|
|
362
|
+
}
|
|
363
|
+
int button = -1;
|
|
364
|
+
int clicks = 0;
|
|
365
|
+
if (XT_IS_OBJECT(options)) {
|
|
366
|
+
button = (int)xt_gui_number_or(xt_object_get_cstr(options, "button"), -1);
|
|
367
|
+
clicks = (int)xt_gui_number_or(xt_object_get_cstr(options, "clicks"), 0);
|
|
368
|
+
}
|
|
369
|
+
xt_gui_dispatch_pointer(win, type, (float)x, (float)y, button, clicks);
|
|
370
|
+
return XT_TRUE;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* -- prototype ------------------------------------------------------------ */
|
|
374
|
+
|
|
375
|
+
static void define_method(xt_value proto, const char *name, void *fn) {
|
|
376
|
+
xt_object_set(proto, xt_string_from_cstr(name), xt_closure_new(fn, 0, NULL));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
xt_value xt_gui_window_proto(void) {
|
|
380
|
+
if (XT_IS_OBJECT(g_window_proto)) return g_window_proto;
|
|
381
|
+
xt_value proto = xt_object_new();
|
|
382
|
+
define_method(proto, "setTitle", (void *)win_set_title);
|
|
383
|
+
define_method(proto, "setSize", (void *)win_set_size);
|
|
384
|
+
define_method(proto, "loadHTML", (void *)win_load_html);
|
|
385
|
+
define_method(proto, "getHTML", (void *)win_get_html);
|
|
386
|
+
define_method(proto, "computedStyle", (void *)win_computed_style);
|
|
387
|
+
define_method(proto, "documentTree", (void *)win_document_tree);
|
|
388
|
+
define_method(proto, "queryCount", (void *)win_query_count);
|
|
389
|
+
define_method(proto, "getBoundingClientRect", (void *)win_get_bounding_rect);
|
|
390
|
+
define_method(proto, "layoutTree", (void *)win_layout_tree);
|
|
391
|
+
define_method(proto, "setBackground", (void *)win_set_background);
|
|
392
|
+
define_method(proto, "paintList", (void *)win_paint_list);
|
|
393
|
+
define_method(proto, "paintCount", (void *)win_paint_count);
|
|
394
|
+
define_method(proto, "advance", (void *)win_advance);
|
|
395
|
+
define_method(proto, "measureText", (void *)win_measure_text);
|
|
396
|
+
define_method(proto, "fontMetrics", (void *)win_font_metrics);
|
|
397
|
+
define_method(proto, "close", (void *)win_close);
|
|
398
|
+
define_method(proto, "isOpen", (void *)win_is_open);
|
|
399
|
+
define_method(proto, "on", (void *)win_on);
|
|
400
|
+
define_method(proto, "off", (void *)win_off);
|
|
401
|
+
define_method(proto, "hitTest", (void *)win_hit_test);
|
|
402
|
+
define_method(proto, "sendEvent", (void *)win_send_event);
|
|
403
|
+
g_window_proto = proto;
|
|
404
|
+
return proto;
|
|
405
|
+
}
|