bare-ui-kit 0.2.0 → 0.3.0

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.
Files changed (89) hide show
  1. package/CMakeLists.txt +7 -1
  2. package/README.md +42 -1
  3. package/binding.m +558 -2
  4. package/index.d.ts +41 -0
  5. package/index.js +16 -0
  6. package/lib/activity-indicator-view.d.ts +29 -0
  7. package/lib/activity-indicator-view.h +181 -0
  8. package/lib/activity-indicator-view.js +56 -0
  9. package/lib/alert-action.d.ts +33 -0
  10. package/lib/alert-action.js +48 -0
  11. package/lib/alert-controller.d.ts +20 -0
  12. package/lib/alert-controller.h +199 -0
  13. package/lib/alert-controller.js +33 -0
  14. package/lib/attributed-string.d.ts +45 -0
  15. package/lib/attributed-string.h +176 -0
  16. package/lib/attributed-string.js +51 -0
  17. package/lib/attributes.js +34 -0
  18. package/lib/bezier-path.d.ts +26 -0
  19. package/lib/bezier-path.h +145 -0
  20. package/lib/bezier-path.js +51 -0
  21. package/lib/bridging.h +600 -2
  22. package/lib/color.d.ts +86 -0
  23. package/lib/color.h +286 -0
  24. package/lib/color.js +170 -0
  25. package/lib/events.js +35 -0
  26. package/lib/font-descriptor.d.ts +30 -0
  27. package/lib/font-descriptor.h +96 -0
  28. package/lib/font-descriptor.js +47 -0
  29. package/lib/font-metrics.d.ts +38 -0
  30. package/lib/font-metrics.h +109 -0
  31. package/lib/font-metrics.js +58 -0
  32. package/lib/font.d.ts +59 -0
  33. package/lib/font.h +424 -0
  34. package/lib/font.js +100 -0
  35. package/lib/handle.d.ts +5 -0
  36. package/lib/handle.js +6 -0
  37. package/lib/image-view.d.ts +15 -0
  38. package/lib/image-view.h +75 -0
  39. package/lib/image-view.js +27 -0
  40. package/lib/image.d.ts +37 -0
  41. package/lib/image.h +205 -0
  42. package/lib/image.js +60 -0
  43. package/lib/label.d.ts +51 -0
  44. package/lib/label.h +331 -0
  45. package/lib/label.js +94 -0
  46. package/lib/paragraph-style.d.ts +20 -0
  47. package/lib/paragraph-style.h +94 -0
  48. package/lib/paragraph-style.js +42 -0
  49. package/lib/pasteboard.d.ts +31 -0
  50. package/lib/pasteboard.h +123 -0
  51. package/lib/pasteboard.js +63 -0
  52. package/lib/retain.js +12 -0
  53. package/lib/runtime.m +92 -15
  54. package/lib/scene.d.ts +30 -0
  55. package/lib/scene.h +87 -0
  56. package/lib/scene.js +48 -0
  57. package/lib/scratch.js +4 -0
  58. package/lib/screen.d.ts +26 -0
  59. package/lib/screen.h +194 -0
  60. package/lib/screen.js +52 -0
  61. package/lib/scroll-view.d.ts +39 -0
  62. package/lib/scroll-view.h +246 -0
  63. package/lib/scroll-view.js +64 -0
  64. package/lib/switch.d.ts +22 -0
  65. package/lib/switch.h +166 -0
  66. package/lib/switch.js +42 -0
  67. package/lib/text-field.d.ts +103 -0
  68. package/lib/text-field.h +562 -0
  69. package/lib/text-field.js +183 -0
  70. package/lib/text-view.d.ts +59 -0
  71. package/lib/text-view.h +497 -0
  72. package/lib/text-view.js +138 -0
  73. package/lib/view-controller.d.ts +37 -0
  74. package/lib/view-controller.h +108 -20
  75. package/lib/view-controller.js +50 -5
  76. package/lib/view.d.ts +158 -0
  77. package/lib/view.h +1385 -20
  78. package/lib/view.js +276 -7
  79. package/lib/window.d.ts +44 -0
  80. package/lib/window.h +167 -27
  81. package/lib/window.js +62 -9
  82. package/lib/wrap.js +7 -0
  83. package/package.json +12 -3
  84. package/prebuilds/ios-arm64/bare +0 -0
  85. package/prebuilds/ios-arm64/bare-ui-kit.bare +0 -0
  86. package/prebuilds/ios-arm64-simulator/bare +0 -0
  87. package/prebuilds/ios-arm64-simulator/bare-ui-kit.bare +0 -0
  88. package/prebuilds/ios-x64-simulator/bare +0 -0
  89. package/prebuilds/ios-x64-simulator/bare-ui-kit.bare +0 -0
package/lib/view.js CHANGED
@@ -1,29 +1,298 @@
1
1
  const EventEmitter = require('bare-events')
2
2
  const binding = require('../binding')
3
+ const registry = require('bare-foundation-registry')
4
+ const { adopt } = require('./handle')
5
+ const scratch = require('./scratch')
6
+ const observe = require('./events')
7
+ const wrap = require('./wrap')
8
+ const UIKitColor = require('./color')
3
9
 
4
- module.exports = class UIKitView extends EventEmitter {
5
- constructor(handle = null) {
10
+ const EVENTS = {
11
+ [binding.VIEW_EVENT_TOUCHES_BEGAN]: 'touchesBegan',
12
+ [binding.VIEW_EVENT_TOUCHES_MOVED]: 'touchesMoved',
13
+ [binding.VIEW_EVENT_TOUCHES_ENDED]: 'touchesEnded',
14
+ [binding.VIEW_EVENT_TOUCHES_CANCELLED]: 'touchesCancelled'
15
+ }
16
+
17
+ // The wrapper the superview already has. None is made, because it would be
18
+ // garbage straight away.
19
+ function holder(tag) {
20
+ const superview = binding.viewSuperview(tag)
21
+
22
+ if (superview === null) return null
23
+
24
+ return binding.wrapper(superview) || null
25
+ }
26
+
27
+ module.exports = exports = class UIKitView extends EventEmitter {
28
+ constructor(opts = {}) {
6
29
  super()
7
30
 
8
- this._handle = handle
31
+ const { tag = null } = opts
32
+
33
+ this._tag = tag === null ? this._init(opts) : tag
34
+ this._retained = new Set()
35
+
36
+ this._token = binding.claim(this._tag, this)
37
+
38
+ observe(this)
39
+ }
40
+
41
+ get [registry.tag]() {
42
+ return this._tag
43
+ }
44
+
45
+ get [registry.handle]() {
46
+ return binding.handle(this._tag)
47
+ }
48
+
49
+ _init(opts) {
50
+ const { x = 0, y = 0, width = 0, height = 0 } = opts
51
+
52
+ return binding.viewInit(x, y, width, height, this)
53
+ }
54
+
55
+ get frame() {
56
+ binding.viewFrameInto(this._tag, scratch.buffer, 0)
57
+
58
+ return { x: scratch[0], y: scratch[1], width: scratch[2], height: scratch[3] }
59
+ }
60
+
61
+ set frame(frame) {
62
+ const { x = 0, y = 0, width = 0, height = 0 } = frame
63
+
64
+ binding.viewFrame(this._tag, x, y, width, height)
65
+ }
66
+
67
+ get bounds() {
68
+ binding.viewBoundsInto(this._tag, scratch.buffer, 0)
69
+
70
+ return { x: scratch[0], y: scratch[1], width: scratch[2], height: scratch[3] }
71
+ }
72
+
73
+ set bounds(bounds) {
74
+ const { x = 0, y = 0, width = 0, height = 0 } = bounds
75
+
76
+ binding.viewBounds(this._tag, x, y, width, height)
9
77
  }
10
78
 
11
79
  get hidden() {
12
- return binding.viewHidden(this._handle)
80
+ return binding.viewHidden(this._tag)
81
+ }
82
+
83
+ set hidden(hidden) {
84
+ binding.viewHidden(this._tag, hidden)
85
+ }
86
+
87
+ get alpha() {
88
+ return binding.viewAlpha(this._tag)
89
+ }
90
+
91
+ set alpha(alpha) {
92
+ binding.viewAlpha(this._tag, alpha)
93
+ }
94
+
95
+ get contentMode() {
96
+ return binding.viewContentMode(this._tag)
97
+ }
98
+
99
+ set contentMode(contentMode) {
100
+ binding.viewContentMode(this._tag, contentMode)
101
+ }
102
+
103
+ get clipsToBounds() {
104
+ return binding.viewClipsToBounds(this._tag)
105
+ }
106
+
107
+ set clipsToBounds(clipsToBounds) {
108
+ binding.viewClipsToBounds(this._tag, clipsToBounds)
109
+ }
110
+
111
+ get userInteractionEnabled() {
112
+ return binding.viewUserInteractionEnabled(this._tag)
113
+ }
114
+
115
+ set userInteractionEnabled(userInteractionEnabled) {
116
+ binding.viewUserInteractionEnabled(this._tag, userInteractionEnabled)
117
+ }
118
+
119
+ get backgroundColor() {
120
+ return wrap(UIKitColor, binding.viewBackgroundColor(this._tag))
121
+ }
122
+
123
+ set backgroundColor(backgroundColor) {
124
+ binding.viewBackgroundColor(this._tag, adopt(backgroundColor))
125
+ }
126
+
127
+ get tintColor() {
128
+ return wrap(UIKitColor, binding.viewTintColor(this._tag))
129
+ }
130
+
131
+ set tintColor(tintColor) {
132
+ binding.viewTintColor(this._tag, adopt(tintColor))
133
+ }
134
+
135
+ get safeAreaInsets() {
136
+ binding.viewSafeAreaInsetsInto(this._tag, scratch.buffer, 0)
137
+
138
+ return { top: scratch[0], left: scratch[1], bottom: scratch[2], right: scratch[3] }
139
+ }
140
+
141
+ get superview() {
142
+ return wrap(UIKitView, binding.viewSuperview(this._tag))
143
+ }
144
+
145
+ get subviews() {
146
+ return binding.viewSubviews(this._tag).map((tag) => wrap(UIKitView, tag))
13
147
  }
14
148
 
15
- set hidden(value) {
16
- binding.viewHidden(this._handle, value)
149
+ // Holding the wrapper keeps its listeners alive. Only one of our views should
150
+ // hold it, so the previous superview lets go. UIKit detaches the native view
151
+ // itself.
152
+ _attach(view) {
153
+ const tag = adopt(view)
154
+ const superview = holder(tag)
155
+
156
+ if (superview !== null) superview._retained.delete(view)
157
+
158
+ this._retained.add(view)
159
+
160
+ return tag
17
161
  }
18
162
 
19
163
  addSubview(view) {
20
- binding.viewAddSubview(this._handle, view._handle)
164
+ binding.viewAddSubview(this._tag, this._attach(view))
165
+ return this
166
+ }
167
+
168
+ insertSubviewAtIndex(view, index) {
169
+ binding.viewInsertSubviewAtIndex(this._tag, this._attach(view), index)
170
+ return this
171
+ }
172
+
173
+ insertSubviewBelowSubview(view, sibling) {
174
+ binding.viewInsertSubviewBelowSubview(this._tag, this._attach(view), adopt(sibling))
175
+ return this
176
+ }
177
+
178
+ insertSubviewAboveSubview(view, sibling) {
179
+ binding.viewInsertSubviewAboveSubview(this._tag, this._attach(view), adopt(sibling))
21
180
  return this
22
181
  }
23
182
 
183
+ removeFromSuperview() {
184
+ const superview = holder(this._tag)
185
+
186
+ if (superview !== null) superview._retained.delete(this)
187
+
188
+ binding.viewRemoveFromSuperview(this._tag)
189
+
190
+ return this
191
+ }
192
+
193
+ setNeedsLayout() {
194
+ binding.viewSetNeedsLayout(this._tag)
195
+ return this
196
+ }
197
+
198
+ setNeedsDisplay() {
199
+ binding.viewSetNeedsDisplay(this._tag)
200
+ return this
201
+ }
202
+
203
+ endEditing(force = true) {
204
+ return binding.viewEndEditing(this._tag, force)
205
+ }
206
+
207
+ convertPointToView(x, y, view = null) {
208
+ return binding.viewConvertPointToView(this._tag, x, y, view === null ? null : view._tag)
209
+ }
210
+
211
+ convertPointFromView(x, y, view = null) {
212
+ return binding.viewConvertPointFromView(this._tag, x, y, view === null ? null : view._tag)
213
+ }
214
+
215
+ sizeThatFits(width, height) {
216
+ binding.viewSizeThatFitsInto(this._tag, width, height, scratch.buffer, 0)
217
+
218
+ return { width: scratch[0], height: scratch[1] }
219
+ }
220
+
221
+ becomeFirstResponder() {
222
+ return binding.viewBecomeFirstResponder(this._tag)
223
+ }
224
+
225
+ resignFirstResponder() {
226
+ return binding.viewResignFirstResponder(this._tag)
227
+ }
228
+
229
+ get firstResponder() {
230
+ return binding.viewIsFirstResponder(this._tag)
231
+ }
232
+
233
+ sizeToFit() {
234
+ binding.viewSizeToFit(this._tag)
235
+ return this
236
+ }
237
+
238
+ get overrideUserInterfaceStyle() {
239
+ return binding.viewOverrideUserInterfaceStyle(this._tag)
240
+ }
241
+
242
+ set overrideUserInterfaceStyle(style) {
243
+ binding.viewOverrideUserInterfaceStyle(this._tag, style)
244
+ }
245
+
246
+ get userInterfaceStyle() {
247
+ return binding.viewUserInterfaceStyle(this._tag)
248
+ }
249
+
250
+ _ontraitchange() {
251
+ this.emit('traitChange')
252
+ }
253
+
254
+ // UIKit reports touches together, and the binding sends them one at a time.
255
+ _onevent(type, x, y, pointerId) {
256
+ const name = EVENTS[type]
257
+
258
+ if (name === undefined) return
259
+
260
+ this.emit(name, { x, y, pointerId })
261
+ }
262
+
24
263
  [Symbol.for('bare.inspect')]() {
25
264
  return {
26
265
  __proto__: { constructor: UIKitView }
27
266
  }
28
267
  }
29
268
  }
269
+
270
+ // The same bits as the map above, by event name.
271
+ exports._events = {}
272
+
273
+ for (const bit in EVENTS) exports._events[EVENTS[bit]] = Number(bit)
274
+
275
+ // A trait change has a callback of its own, so its bit is added separately.
276
+ exports._events.traitChange = binding.VIEW_EVENT_TRAIT_CHANGE
277
+
278
+ exports.USER_INTERFACE_STYLE = {
279
+ UNSPECIFIED: binding.USER_INTERFACE_STYLE_UNSPECIFIED,
280
+ LIGHT: binding.USER_INTERFACE_STYLE_LIGHT,
281
+ DARK: binding.USER_INTERFACE_STYLE_DARK
282
+ }
283
+
284
+ exports.CONTENT_MODE = {
285
+ SCALE_TO_FILL: binding.VIEW_CONTENT_MODE_SCALE_TO_FILL,
286
+ SCALE_ASPECT_FIT: binding.VIEW_CONTENT_MODE_SCALE_ASPECT_FIT,
287
+ SCALE_ASPECT_FILL: binding.VIEW_CONTENT_MODE_SCALE_ASPECT_FILL,
288
+ REDRAW: binding.VIEW_CONTENT_MODE_REDRAW,
289
+ CENTER: binding.VIEW_CONTENT_MODE_CENTER,
290
+ TOP: binding.VIEW_CONTENT_MODE_TOP,
291
+ BOTTOM: binding.VIEW_CONTENT_MODE_BOTTOM,
292
+ LEFT: binding.VIEW_CONTENT_MODE_LEFT,
293
+ RIGHT: binding.VIEW_CONTENT_MODE_RIGHT,
294
+ TOP_LEFT: binding.VIEW_CONTENT_MODE_TOP_LEFT,
295
+ TOP_RIGHT: binding.VIEW_CONTENT_MODE_TOP_RIGHT,
296
+ BOTTOM_LEFT: binding.VIEW_CONTENT_MODE_BOTTOM_LEFT,
297
+ BOTTOM_RIGHT: binding.VIEW_CONTENT_MODE_BOTTOM_RIGHT
298
+ }
@@ -0,0 +1,44 @@
1
+ import { tag, handle, Handle, Wrapper } from 'bare-foundation-registry'
2
+ import UIKitView = require('./view')
3
+ import UIKitScene = require('./scene')
4
+ import UIKitViewController = require('./view-controller')
5
+
6
+ /** A window, as a `UIWindow`. */
7
+ interface UIKitWindow extends UIKitView<UIKitWindow.Events> {
8
+ get rootViewController(): UIKitViewController | null
9
+ set rootViewController(viewController: Wrapper | null)
10
+
11
+ get windowScene(): UIKitScene | null
12
+ set windowScene(scene: Wrapper | null)
13
+
14
+ /** Whether the window gets keyboard input. */
15
+ readonly keyWindow: boolean
16
+
17
+ makeKeyWindow(): this
18
+
19
+ /** Show the window and make it get keyboard input. The window is kept alive from then on. */
20
+ makeKeyAndVisible(): this
21
+ }
22
+
23
+ declare class UIKitWindow {
24
+ /**
25
+ * Create a window in `scene`. Without a frame, the window fills its scene. Give any frame field
26
+ * to set the frame, and the missing ones are 0. A window without a scene is never shown.
27
+ */
28
+ constructor(opts?: {
29
+ scene?: Wrapper | null
30
+ x?: number
31
+ y?: number
32
+ width?: number
33
+ height?: number
34
+ })
35
+ }
36
+
37
+ declare namespace UIKitWindow {
38
+ export interface Events {
39
+ /** The keyboard is about to move to this frame, in screen coordinates. */
40
+ keyboardWillChangeFrame: [frame: { x: number; y: number; width: number; height: number }]
41
+ }
42
+ }
43
+
44
+ export = UIKitWindow
package/lib/window.h CHANGED
@@ -6,10 +6,19 @@
6
6
 
7
7
  #import "bridging.h"
8
8
 
9
- @interface BareWindow : UIWindow {
9
+ // The keyboard is reported as a notification, carrying where it will be when it
10
+ // stops moving. A window is what that frame is measured against, so a window
11
+ // observes it while the mask asks.
12
+ enum {
13
+ bare_ui_kit_window_event_keyboard_will_change_frame = 1 << 0,
14
+ };
15
+
16
+ @interface BareWindow : UIWindow <BareEventTarget> {
10
17
  @public
11
18
  js_env_t *env;
12
19
  js_ref_t *ctx;
20
+
21
+ int32_t mask;
13
22
  }
14
23
 
15
24
  @end
@@ -19,37 +28,95 @@
19
28
  - (void)dealloc {
20
29
  int err;
21
30
 
31
+ [NSNotificationCenter.defaultCenter removeObserver:self];
32
+
22
33
  err = js_delete_reference(env, ctx);
23
34
  assert(err == 0);
24
35
 
25
36
  [super dealloc];
26
37
  }
27
38
 
39
+ - (int32_t)eventMask {
40
+ return mask;
41
+ }
42
+
43
+ - (void)setEventMask:(int32_t)value {
44
+ int32_t changed = mask ^ value;
45
+
46
+ mask = value;
47
+
48
+ if ((changed & bare_ui_kit_window_event_keyboard_will_change_frame) == 0) return;
49
+
50
+ if ((value & bare_ui_kit_window_event_keyboard_will_change_frame) != 0) {
51
+ [NSNotificationCenter.defaultCenter
52
+ addObserver:self
53
+ selector:@selector(bareKeyboardWillChangeFrame:)
54
+ name:UIKeyboardWillChangeFrameNotification
55
+ object:nil];
56
+ } else {
57
+ [NSNotificationCenter.defaultCenter
58
+ removeObserver:self
59
+ name:UIKeyboardWillChangeFrameNotification
60
+ object:nil];
61
+ }
62
+ }
63
+
64
+ - (void)bareKeyboardWillChangeFrame:(NSNotification *)notification {
65
+ NSValue *frame = notification.userInfo[UIKeyboardFrameEndUserInfoKey];
66
+
67
+ if (frame == nil) return;
68
+
69
+ // In screen coordinates, as the notification reports it.
70
+ bare_ui_kit__emit_rect(env, ctx, "_onkeyboardwillchangeframe", [frame CGRectValue]);
71
+ }
72
+
28
73
  @end
29
74
 
75
+ // A window without a scene is never shown.
30
76
  static js_value_t *
31
77
  bare_ui_kit_window_init(js_env_t *env, js_callback_info_t *info) {
32
78
  int err;
33
79
 
34
- size_t argc = 1;
35
- js_value_t *argv[1];
80
+ size_t argc = 6;
81
+ js_value_t *argv[6];
36
82
 
37
- err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
83
+ bare_ui_kit_state_t *state;
84
+ err = js_get_callback_info(env, info, &argc, argv, NULL, (void **) &state);
38
85
  assert(err == 0);
39
86
 
40
- assert(argc == 1);
87
+ assert(argc == 6);
88
+
89
+ js_value_type_t type;
90
+ err = js_typeof(env, argv[1], &type);
91
+ assert(err == 0);
92
+
93
+ bool framed = type != js_null;
94
+
95
+ double x = 0, y = 0, width = 0, height = 0;
96
+
97
+ if (framed) {
98
+ if (!bare_ui_kit__read_double(env, argv[1], "x", &x)) return NULL;
99
+ if (!bare_ui_kit__read_double(env, argv[2], "y", &y)) return NULL;
100
+ if (!bare_ui_kit__read_double(env, argv[3], "width", &width)) return NULL;
101
+ if (!bare_ui_kit__read_double(env, argv[4], "height", &height)) return NULL;
102
+ }
41
103
 
42
104
  js_value_t *result;
43
105
 
44
106
  @autoreleasepool {
45
- BareWindow *handle = [[BareWindow alloc] init];
107
+ UIWindowScene *scene = bare_foundation_to_object(env, state->registry, argv[0]);
46
108
 
47
- err = js_create_external(env, (void *) CFBridgingRetain(handle), bare_ui_kit__on_bridged_release, NULL, &result);
48
- assert(err == 0);
109
+ BareWindow *handle = scene
110
+ ? [[[BareWindow alloc] initWithWindowScene:scene] autorelease]
111
+ : [[[BareWindow alloc] initWithFrame:CGRectZero] autorelease];
112
+
113
+ if (framed) handle.frame = CGRectMake(x, y, width, height);
114
+
115
+ result = bare_foundation_bridge(env, state->registry, handle);
49
116
 
50
117
  handle->env = env;
51
118
 
52
- err = js_create_reference(env, argv[0], 1, &handle->ctx);
119
+ err = js_create_reference(env, argv[5], 0, &handle->ctx);
53
120
  assert(err == 0);
54
121
  }
55
122
 
@@ -57,20 +124,20 @@ bare_ui_kit_window_init(js_env_t *env, js_callback_info_t *info) {
57
124
  }
58
125
 
59
126
  static js_value_t *
60
- bare_ui_kit_window_root_view_controller(js_env_t *env, js_callback_info_t *info) {
127
+ bare_ui_kit_window_window_scene(js_env_t *env, js_callback_info_t *info) {
61
128
  int err;
62
129
 
63
130
  size_t argc = 2;
64
131
  js_value_t *argv[2];
65
132
 
66
- err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
133
+ bare_ui_kit_state_t *state;
134
+ err = js_get_callback_info(env, info, &argc, argv, NULL, (void **) &state);
67
135
  assert(err == 0);
68
136
 
69
137
  assert(argc == 1 || argc == 2);
70
138
 
71
139
  void *handle;
72
- err = js_get_value_external(env, argv[0], &handle);
73
- assert(err == 0);
140
+ if (bare_foundation_read_tag(env, state->registry, argv[0], "handle", &handle) < 0) return NULL;
74
141
 
75
142
  js_value_t *result = NULL;
76
143
 
@@ -78,20 +145,40 @@ bare_ui_kit_window_root_view_controller(js_env_t *env, js_callback_info_t *info)
78
145
  UIWindow *window = (__bridge UIWindow *) handle;
79
146
 
80
147
  if (argc == 1) {
81
- UIViewController *view_controller = window.rootViewController;
148
+ result = bare_foundation_bridge(env, state->registry, window.windowScene);
149
+ } else {
150
+ window.windowScene = bare_foundation_to_object(env, state->registry, argv[1]);
151
+ }
152
+ }
82
153
 
83
- if (view_controller == NULL) return NULL;
154
+ return result;
155
+ }
84
156
 
85
- err = js_create_external(env, (void *) CFBridgingRetain(handle), bare_ui_kit__on_bridged_release, NULL, &result);
86
- assert(err == 0);
87
- } else {
88
- void *handle;
89
- err = js_get_value_external(env, argv[1], &handle);
90
- assert(err == 0);
157
+ static js_value_t *
158
+ bare_ui_kit_window_root_view_controller(js_env_t *env, js_callback_info_t *info) {
159
+ int err;
91
160
 
92
- UIViewController *view_controller = (__bridge UIViewController *) handle;
161
+ size_t argc = 2;
162
+ js_value_t *argv[2];
163
+
164
+ bare_ui_kit_state_t *state;
165
+ err = js_get_callback_info(env, info, &argc, argv, NULL, (void **) &state);
166
+ assert(err == 0);
167
+
168
+ assert(argc == 1 || argc == 2);
93
169
 
94
- window.rootViewController = view_controller;
170
+ void *handle;
171
+ if (bare_foundation_read_tag(env, state->registry, argv[0], "handle", &handle) < 0) return NULL;
172
+
173
+ js_value_t *result = NULL;
174
+
175
+ @autoreleasepool {
176
+ UIWindow *window = (__bridge UIWindow *) handle;
177
+
178
+ if (argc == 1) {
179
+ result = bare_foundation_bridge(env, state->registry, window.rootViewController);
180
+ } else {
181
+ window.rootViewController = bare_foundation_to_object(env, state->registry, argv[1]);
95
182
  }
96
183
  }
97
184
 
@@ -105,20 +192,73 @@ bare_ui_kit_window_make_key_window(js_env_t *env, js_callback_info_t *info) {
105
192
  size_t argc = 1;
106
193
  js_value_t *argv[1];
107
194
 
108
- err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
195
+ bare_ui_kit_state_t *state;
196
+ err = js_get_callback_info(env, info, &argc, argv, NULL, (void **) &state);
109
197
  assert(err == 0);
110
198
 
111
199
  assert(argc == 1);
112
200
 
113
201
  void *handle;
114
- err = js_get_value_external(env, argv[0], &handle);
115
- assert(err == 0);
202
+ if (bare_foundation_read_tag(env, state->registry, argv[0], "handle", &handle) < 0) return NULL;
116
203
 
117
204
  @autoreleasepool {
118
- BareWindow *window = (__bridge BareWindow *) handle;
205
+ UIWindow *window = (__bridge UIWindow *) handle;
119
206
 
120
207
  [window makeKeyWindow];
121
208
  }
122
209
 
123
210
  return NULL;
124
211
  }
212
+
213
+ static js_value_t *
214
+ bare_ui_kit_window_make_key_and_visible(js_env_t *env, js_callback_info_t *info) {
215
+ int err;
216
+
217
+ size_t argc = 1;
218
+ js_value_t *argv[1];
219
+
220
+ bare_ui_kit_state_t *state;
221
+ err = js_get_callback_info(env, info, &argc, argv, NULL, (void **) &state);
222
+ assert(err == 0);
223
+
224
+ assert(argc == 1);
225
+
226
+ void *handle;
227
+ if (bare_foundation_read_tag(env, state->registry, argv[0], "handle", &handle) < 0) return NULL;
228
+
229
+ @autoreleasepool {
230
+ UIWindow *window = (__bridge UIWindow *) handle;
231
+
232
+ [window makeKeyAndVisible];
233
+ }
234
+
235
+ return NULL;
236
+ }
237
+
238
+ static js_value_t *
239
+ bare_ui_kit_window_key_window(js_env_t *env, js_callback_info_t *info) {
240
+ int err;
241
+
242
+ size_t argc = 1;
243
+ js_value_t *argv[1];
244
+
245
+ bare_ui_kit_state_t *state;
246
+ err = js_get_callback_info(env, info, &argc, argv, NULL, (void **) &state);
247
+ assert(err == 0);
248
+
249
+ assert(argc == 1);
250
+
251
+ void *handle;
252
+ if (bare_foundation_read_tag(env, state->registry, argv[0], "handle", &handle) < 0) return NULL;
253
+
254
+ js_value_t *result;
255
+
256
+ @autoreleasepool {
257
+ UIWindow *window = (__bridge UIWindow *) handle;
258
+
259
+ err = js_get_boolean(env, window.keyWindow, &result);
260
+ assert(err == 0);
261
+ }
262
+
263
+ return result;
264
+ }