FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix: composition helper · NativeScript/windows@0fb260d · GitHub

Repository navigation

Commit 0fb260d

Browse files
committed
fix: composition helper
1 parent 481585f commit 0fb260d

12 files changed

Lines changed: 929 additions & 5 deletions

File tree

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
(function () {
2+
// Small demo: create/update/remove a composition border using runtime helpers
3+
// Falls back to warnings if the runtime bindings are not exposed to JS.
4+
5+
function resolveCreateFn() {
6+
if (typeof NSWinRT !== 'undefined' && typeof NSWinRT.createCompositionBorder === 'function') return NSWinRT.createCompositionBorder;
7+
if (typeof runtime_create_border_instance === 'function') return runtime_create_border_instance;
8+
if (typeof NSWinRT !== 'undefined' && typeof NSWinRT.createBorder === 'function') return NSWinRT.createBorder;
9+
return null;
10+
}
11+
12+
function resolveSetFn() {
13+
if (typeof runtime_set_border === 'function') return runtime_set_border;
14+
if (typeof NSWinRT !== 'undefined' && typeof NSWinRT.setBorder === 'function') return NSWinRT.setBorder;
15+
return null;
16+
}
17+
18+
function resolveFreeFn() {
19+
if (typeof runtime_free_border_instance === 'function') return runtime_free_border_instance;
20+
if (typeof NSWinRT !== 'undefined' && typeof NSWinRT.freeBorder === 'function') return NSWinRT.freeBorder;
21+
return null;
22+
}
23+
24+
function createJSBorder(element) {
25+
const createFn = resolveCreateFn();
26+
const setFn = resolveSetFn();
27+
const freeFn = resolveFreeFn();
28+
29+
if (!createFn) {
30+
console.warn('Border demo: runtime_create_border_instance not available.');
31+
return null;
32+
}
33+
34+
// If the runtime provides the new higher-level helper, use it and
35+
// return the proxy object directly (it auto-finalizes on GC).
36+
if (typeof NSWinRT !== 'undefined' && typeof NSWinRT.createCompositionBorder === 'function') {
37+
try {
38+
return NSWinRT.createCompositionBorder(element);
39+
} catch (e) {
40+
console.warn('createCompositionBorder failed:', e);
41+
}
42+
}
43+
44+
// Many WinRT proxies expose an internal numeric handle as `__handle`.
45+
const elHandle = (element && typeof element === 'object' && typeof element.__handle === 'number')
46+
? element.__handle
47+
: element;
48+
49+
const id = createFn(elHandle);
50+
if (!id) {
51+
console.warn('Border demo: create returned falsy id');
52+
return null;
53+
}
54+
55+
const holder = { id, element };
56+
57+
// Install shared finalizer registry on window so GC will free the native instance.
58+
if (typeof FinalizationRegistry === 'function') {
59+
if (!window.__ns_border_finalizer) {
60+
window.__ns_border_finalizer = new FinalizationRegistry(function (id) {
61+
try {
62+
const f = resolveFreeFn();
63+
if (f) f(id);
64+
} catch (e) {}
65+
});
66+
}
67+
window.__ns_border_finalizer.register(holder, id);
68+
}
69+
70+
holder.update = function (left, top, right, bottom, color, r_tl, r_tr, r_br, r_bl) {
71+
const f = resolveSetFn();
72+
if (!f) { console.warn('Border demo: runtime_set_border not available'); return; }
73+
f(id, left, top, right, bottom, color, r_tl, r_tr, r_br, r_bl);
74+
};
75+
76+
holder.free = function () {
77+
const f = resolveFreeFn();
78+
if (f) f(id);
79+
};
80+
81+
return holder;
82+
}
83+
84+
function runDemo() {
85+
try {
86+
const window = Windows.UI.Xaml.Window.Current;
87+
const panel = new Windows.UI.Xaml.Controls.StackPanel();
88+
panel.Orientation = Windows.UI.Xaml.Controls.Orientation.Vertical;
89+
90+
const sample = new Windows.UI.Xaml.Controls.Border();
91+
sample.Width = 320;
92+
sample.Height = 160;
93+
sample.Margin = new Windows.UI.Xaml.Thickness(20);
94+
sample.Background = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Colors.AliceBlue);
95+
96+
panel.Children.Append(sample);
97+
98+
const status = new Windows.UI.Xaml.Controls.TextBlock();
99+
status.Text = 'Border demo: initializing...';
100+
status.Margin = new Windows.UI.Xaml.Thickness(20, 6, 20, 20);
101+
panel.Children.Append(status);
102+
103+
window.Content = panel;
104+
window.Activate();
105+
106+
const holder = createJSBorder(sample);
107+
if (!holder) {
108+
status.Text = 'Border demo: runtime bindings not available.';
109+
return;
110+
}
111+
112+
status.Text = 'Border demo: created instance ' + holder.id;
113+
114+
// initial border: 4px all sides, blue, radius 8
115+
holder.update(4, 4, 4, 4, 0xFF0078D7, 8, 8, 8, 8);
116+
117+
// update after 2s
118+
setTimeout(function () {
119+
holder.update(8, 2, 8, 2, 0xFF00C853, 16, 8, 12, 4);
120+
status.Text = 'Border demo: updated';
121+
}, 2000);
122+
123+
// drop after 6s so runtime finalizer/unloaded handlers perform cleanup
124+
setTimeout(function () {
125+
window.__demo_border_holder = null;
126+
status.Text = 'Border demo: dropped holder (runtime will clean up)';
127+
}, 6000);
128+
129+
// keep a debug reference so you can inspect it in devtools
130+
window.__demo_border_holder = holder;
131+
} catch (e) {
132+
console.warn('Border demo failed:', e && e.message ? e.message : e);
133+
}
134+
}
135+
136+
// Auto-run when loaded
137+
if (typeof document === 'undefined') {
138+
try { runDemo(); } catch (e) {}
139+
} else {
140+
document.addEventListener('DOMContentLoaded', runDemo);
141+
}
142+
})();

‎nativescript/src/lib.rs‎

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::ffi::{c_char, CStr, CString};
1+
use std::ffi::{c_char, CStr, CString, c_void};
22
use std::sync::{Once, OnceLock};
33
use std::sync::Arc;
44
use runtime::Runtime;
@@ -213,6 +213,68 @@ pub extern "C" fn runtime_pump_timers() {
213213
});
214214
}
215215

216+
/// Attach a (cached) container visual to the supplied `UIElement` pointer and
217+
/// return the raw visual pointer as an `i64`. Returns 0 on error.
218+
#[no_mangle]
219+
pub extern "C" fn runtime_attach_border_container(element: *mut c_void) -> i64 {
220+
if element.is_null() { return 0; }
221+
let result = std::panic::catch_unwind(|| {
222+
match runtime::composition_border::ensure_container_for_element(element) {
223+
Ok(ptr) => ptr,
224+
Err(err) => {
225+
eprintln!("[NativeScript] runtime_attach_border_container error: {:?}", err);
226+
0
227+
}
228+
}
229+
});
230+
match result {
231+
Ok(v) => v,
232+
Err(_) => 0,
233+
}
234+
}
235+
236+
/// Create a border helper instance attached to `element` and return an opaque id.
237+
#[no_mangle]
238+
pub extern "C" fn runtime_create_border_instance(element: *mut c_void) -> i64 {
239+
if element.is_null() { return 0; }
240+
match runtime::composition_border::create_border_instance(element) {
241+
Ok(id) => id,
242+
Err(err) => {
243+
eprintln!("[NativeScript] runtime_create_border_instance error: {:?}", err);
244+
0
245+
}
246+
}
247+
}
248+
249+
/// Set border on previously created instance. Returns 1 on success, 0 on failure.
250+
#[no_mangle]
251+
pub extern "C" fn runtime_set_border(
252+
instance_id: i64,
253+
left: f32,
254+
top: f32,
255+
right: f32,
256+
bottom: f32,
257+
color: u32,
258+
radius_tl: f32,
259+
radius_tr: f32,
260+
radius_br: f32,
261+
radius_bl: f32,
262+
) -> i32 {
263+
match runtime::composition_border::set_border(instance_id, left, top, right, bottom, color, radius_tl, radius_tr, radius_br, radius_bl) {
264+
Ok(()) => 1,
265+
Err(err) => {
266+
eprintln!("[NativeScript] runtime_set_border error: {:?}", err);
267+
0
268+
}
269+
}
270+
}
271+
272+
/// Free a border instance previously created.
273+
#[no_mangle]
274+
pub extern "C" fn runtime_free_border_instance(instance_id: i64) {
275+
let _ = runtime::composition_border::free_border_instance(instance_id);
276+
}
277+
216278
/// Free a string previously returned by `runtime_devtools_start`.
217279
#[cfg(feature = "devtools")]
218280
#[no_mangle]

‎runtime/Cargo.toml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,14 @@ features = [
4040
"Win32_UI_Shell",
4141
"Win32_UI_WindowsAndMessaging",
4242
"Data_Json",
43+
"UI_Composition",
44+
"Foundation_Numerics",
45+
"Graphics_Imaging",
4346
]
4447

48+
[features]
49+
default = []
50+
4551
[dev-dependencies]
4652
criterion = "0.5"
4753

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL