Chandra

 view release on metacpan or  search on metacpan

Chandra.xs  view on Meta::CPAN

 * 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 )