Chandra
view release on metacpan or search on metacpan
* in per-module XS fragments via INCLUDE:.
*/
#define WEBVIEW_IMPLEMENTATION
#define CHANDRA_XS_IMPLEMENTATION
#define CHANDRA_WINDOW_IMPLEMENTATION
#include "include/chandra/chandra.h"
#include "include/chandra/chandra_error.h"
#include "include/chandra/chandra_bind.h"
#include "include/chandra/chandra_element.h"
#include "include/chandra/chandra_devtools.h"
#include "include/chandra/chandra_internal.h"
#include "include/chandra/chandra_socket_common.h"
#include "include/chandra/chandra_socket_token.h"
#include "include/chandra/chandra_socket_hub.h"
#include "include/chandra/chandra_socket_client.h"
#include "include/chandra/chandra_notify.h"
#include "include/chandra/chandra_store.h"
#include "include/chandra/chandra_log.h"
#include "include/chandra/chandra_assets.h"
#include "include/chandra/chandra_clipboard.h"
#include "include/chandra/chandra_contextmenu.h"
#include "include/chandra/chandra_window.h"
#include "include/chandra/chandra_splash.h"
#include "include/chandra/chandra_form.h"
#include "include/chandra/chandra_bridge_ext.h"
#include "include/chandra/chandra_canvas.h"
/* Window registry - maps native wid to Perl SV* objects */
static HV *_window_registry = NULL;
static IV _window_id_counter = 0;
static void _ensure_registry(pTHX) {
if (!_window_registry) {
_window_registry = newHV();
}
}
static void _register_window(pTHX_ IV wid, SV *obj) {
_ensure_registry(aTHX);
hv_store(_window_registry, (char*)&wid, sizeof(wid), SvREFCNT_inc(obj), 0);
}
static void _unregister_window(pTHX_ IV wid) {
_ensure_registry(aTHX);
hv_delete(_window_registry, (char*)&wid, sizeof(wid), G_DISCARD);
}
static SV *_get_window(pTHX_ IV wid) {
SV **svp;
_ensure_registry(aTHX);
svp = hv_fetch(_window_registry, (char*)&wid, sizeof(wid), 0);
return svp ? *svp : NULL;
}
static IV _get_window_count(pTHX) {
_ensure_registry(aTHX);
return HvKEYS(_window_registry);
}
/* Macros to call the static functions with aTHX */
#define ENSURE_REGISTRY() _ensure_registry(aTHX)
#define REGISTER_WINDOW(wid, obj) _register_window(aTHX_ wid, obj)
#define UNREGISTER_WINDOW(wid) _unregister_window(aTHX_ wid)
#define GET_WINDOW(wid) _get_window(aTHX_ wid)
#define GET_WINDOW_COUNT() _get_window_count(aTHX)
/* Toast state */
static int _toast_id = 0;
static int _toast_injected = 0;
/* Modal state */
static int _modal_id = 0;
static int _modal_injected = 0;
static const char *CHANDRA_TOAST_JS =
"(function(){"
"if(window.__chandraToast)return;"
"var c=document.createElement('div');"
"c.id='__chandra_toast_container';"
"c.style.cssText='position:fixed;top:16px;right:16px;z-index:99999;display:flex;flex-direction:column;gap:8px;pointer-events:none;max-width:380px;';"
"document.body.appendChild(c);"
"var t={};"
"var tc={"
"success:{bg:'var(--chandra-success,#4CAF50)',icon:'\\u2713'},"
"error:{bg:'var(--chandra-danger,#f44336)',icon:'\\u2717'},"
"warning:{bg:'var(--chandra-warning,#ff9800)',icon:'\\u26A0'},"
"info:{bg:'var(--chandra-info,#2196F3)',icon:'\\u2139'}"
"};"
"function show(id,msg,type,dur,act){"
"var o=tc[type]||tc.info;"
"var el=document.createElement('div');"
"el.id=id;el.className='chandra-toast chandra-toast-'+type;"
"el.style.cssText='pointer-events:auto;display:flex;align-items:center;gap:10px;padding:12px 16px;border-radius:var(--chandra-radius,6px);background:var(--chandra-surface,#1e1e1e);color:var(--chandra-text,#e0e0e0);box-shadow:var(--chandra-shadow,0 2p...
"var ic=document.createElement('span');"
"ic.style.cssText='font-size:1.2em;flex-shrink:0;';"
"ic.textContent=o.icon;el.appendChild(ic);"
"var bd=document.createElement('div');"
"bd.style.cssText='flex:1;min-width:0;';"
"bd.textContent=msg;el.appendChild(bd);"
"if(act&&act.label){"
"var btn=document.createElement('button');"
"btn.textContent=act.label;"
"btn.style.cssText='padding:4px 12px;border:1px solid var(--chandra-border,#333);border-radius:var(--chandra-radius,4px);background:transparent;color:var(--chandra-primary,#64B5F6);cursor:pointer;font-size:0.85em;flex-shrink:0;';"
"btn.onclick=function(e){e.stopPropagation();if(act.handler)window.chandra.invoke(act.handler,[]);dismiss(id);};"
"el.appendChild(btn);}"
"var cl=document.createElement('span');"
"cl.textContent='\\u00D7';"
"cl.style.cssText='cursor:pointer;opacity:0.5;font-size:1.2em;flex-shrink:0;padding:0 2px;';"
"cl.onclick=function(e){e.stopPropagation();dismiss(id);};"
"el.appendChild(cl);"
"el.onclick=function(){dismiss(id);};"
"while(c.children.length>=5){var ol=c.firstChild;if(ol)dismiss(ol.id);}"
"c.appendChild(el);t[id]=el;"
"requestAnimationFrame(function(){el.style.opacity='1';el.style.transform='translateX(0)';});"
"if(dur>0)setTimeout(function(){dismiss(id);},dur);}"
"function dismiss(id){"
"var el=t[id];if(!el)return;"
"el.style.opacity='0';el.style.transform='translateX(100%)';"
"setTimeout(function(){if(el.parentNode)el.parentNode.removeChild(el);delete t[id];},300);}"
"window.__chandraToast={show:show,dismiss:dismiss};"
( run in 0.616 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )