initial commit
This commit is contained in:
commit
18255ce4cd
21 changed files with 1244 additions and 0 deletions
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Node
|
||||
node_modules/
|
||||
|
||||
# Milsko
|
||||
deps/
|
||||
*.tar.gz
|
||||
|
||||
# Build
|
||||
build/
|
||||
dist/
|
||||
prebuild/
|
||||
|
||||
# IDE
|
||||
.vscode
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
7
.prettierrc
Normal file
7
.prettierrc
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"trailingComma": "none",
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 4,
|
||||
"useTabs": false
|
||||
}
|
||||
24
LICENSE
Normal file
24
LICENSE
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
Copyright (c) 2026, Pyrite development team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
21
README-es.md
Normal file
21
README-es.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<h1 align="center" title="Milsko for Node.js">
|
||||
<img src="https://forgejo.nishi.boats/pyrite-dev/milsko/raw/branch/master/resource/logo/banner-nodejs.png" alt="Milsko for Node.js logo">
|
||||
</h1>
|
||||
|
||||
> Crea GUIs de escritorio nativas y multi-plataforma con Node.js.
|
||||
|
||||
[English](README.md) • [Español](README-es.md) • [GitHub](https://github.com/pyrite-dev/milsko-node.git) • [Fishy Forgejo](https://forgejo.nishi.boats/pyrite-dev/milsko-node.git) • [Website](https://milsko.nishi.boats)
|
||||
|
||||
Milsko es un conjunto de herramientas para GUIs ligero y multiplataforma diseñado para ser totalmente retrocompatible con sistemas operativos más antiguos, a la vez siendo relativamente moderno.
|
||||
|
||||
Este paquete contiene enlaces orientados a objectos para crear y empaquetar aplicaciones GUI nativas utilizando Node.js.
|
||||
|
||||
## Instalación
|
||||
|
||||
Usa el administrador de paquetes de tu preferencia (también es compatible con Bun). Contiene binarios precompilados por defecto.
|
||||
|
||||
```sh
|
||||
npm install milsko
|
||||
```
|
||||
|
||||
Si no hay binarios precompilados disponibles para tu plataforma o te gustaría compilarlo desde fuente, puedes usar `npm install milsko --build-from-source` o equivalente.
|
||||
20
README.md
Normal file
20
README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<h1 align="center" title="Milsko for Node.js">
|
||||
<img src="https://forgejo.nishi.boats/pyrite-dev/milsko/raw/branch/master/resource/logo/banner-nodejs.png" alt="Milsko for Node.js logo">
|
||||
</h1>
|
||||
|
||||
> Build native cross-platform desktop GUIs with Node.js.
|
||||
|
||||
[English](README.md) • [Español](README-es.md) • [GitHub](https://github.com/pyrite-dev/milsko-node.git) • [Fishy Forgejo](https://forgejo.nishi.boats/pyrite-dev/milsko-node.git) • [Website](https://milsko.nishi.boats)
|
||||
|
||||
Milsko is a lightweight cross-platform GUI toolkit designed to be fully compatible with older OSes while also being reasonably modern.
|
||||
|
||||
This package provides OOP-oriented bindings to create and package fully native GUI appliations with Node.js.
|
||||
|
||||
## Installation
|
||||
Use your preferred package manager (also compatible with Bun). Prebuilt binaries are included by default.
|
||||
|
||||
```sh
|
||||
npm install milsko
|
||||
```
|
||||
|
||||
If none precompiled binaries are available for your platform or if you'd like to build from source, you can use `npm install milsko --build-from-source` or equivalent.
|
||||
79
binding.gyp
Normal file
79
binding.gyp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "milsko",
|
||||
"sources": ["src/milsko.cpp"],
|
||||
"include_dirs": ["<!@(node -p \"require('node-addon-api').include\")"],
|
||||
"dependencies": [
|
||||
"libMw",
|
||||
"<!(node -p \"require('node-addon-api').gyp\")",
|
||||
],
|
||||
"cflags!": ["-fno-exceptions"],
|
||||
"cflags_cc!": ["-fno-exceptions"],
|
||||
"xcode_settings": {
|
||||
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
|
||||
"CLANG_CXX_LIBRARY": "libc++",
|
||||
"MACOSX_DEPLOYMENT_TARGET": "10.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"target_name": "libMw",
|
||||
"type": "shared_library",
|
||||
"sources": [
|
||||
"deps/milsko/src/*.c",
|
||||
"deps/milsko/src/cursor/*.c",
|
||||
"deps/milsko/src/icon/*.c",
|
||||
"deps/milsko/src/widget/*.c",
|
||||
"deps/milsko/src/text/*.c",
|
||||
"deps/milsko/src/text/font/*.c",
|
||||
"deps/milsko/src/dialog/*.c",
|
||||
"deps/milsko/src/abstract/*.c"
|
||||
"deps/milsko/external/*.c",
|
||||
"deps/milsko/external/libz/src/*.c",
|
||||
"deps/milsko/external/stb_image.c",
|
||||
"deps/milsko/external/stb_truetype.c",
|
||||
],
|
||||
"include_dirs": [
|
||||
"deps/milsko/include"
|
||||
"deps/milsko/external"
|
||||
"deps/milsko/external/libz/include"
|
||||
],
|
||||
"defines": [
|
||||
"USE_STB_IMAGE",
|
||||
"USE_STB_TRUETYPE"
|
||||
],
|
||||
"conditions": [
|
||||
# [
|
||||
# "OS=='mac'",
|
||||
# {
|
||||
# "link_settings": {
|
||||
# "ldflags": ["-framework Cocoa -lobjc"]
|
||||
# },
|
||||
# "sources": [
|
||||
# "deps/milsko/src/backend/nococoa.m"
|
||||
# ],
|
||||
# "defines": ["USE_COCOA"]
|
||||
# }
|
||||
# ],
|
||||
[
|
||||
"OS=='win'",
|
||||
{
|
||||
"link_settings": {
|
||||
"ldflags": ["-static-libgcc"]
|
||||
},
|
||||
"sources": [
|
||||
"deps/milsko/src/backend/gdi.c"
|
||||
],
|
||||
"defines": ["USE_GDI"]
|
||||
},
|
||||
{
|
||||
"sources": [
|
||||
"deps/milsko/src/backend/x11.c",
|
||||
],
|
||||
"defines": ["USE_X11"]
|
||||
}
|
||||
],
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
208
bun.lock
Normal file
208
bun.lock
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "milsko",
|
||||
"dependencies": {
|
||||
"node-addon-api": "^8.7.0",
|
||||
"node-gyp-build": "^4.8.4",
|
||||
"tar": "^7.5.13",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^25.6.0",
|
||||
"fast-xml-parser": "^5.6.0",
|
||||
"node-gyp": "^12.2.0",
|
||||
"prebuildify": "^6.0.1",
|
||||
"prettier": "^3.8.2",
|
||||
"rimraf": "^6.1.3",
|
||||
"typescript": "^6.0.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@gar/promise-retry": ["@gar/promise-retry@1.0.3", "", {}, "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA=="],
|
||||
|
||||
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
|
||||
|
||||
"@nodable/entities": ["@nodable/entities@1.1.0", "", {}, "sha512-bidpxmTBP0pOsxULw6XlxzQpTgrAGLDHGBK/JuWhPDL6ZV0GZ/PmN9CA9do6e+A9lYI6qx6ikJUtJYRxup141g=="],
|
||||
|
||||
"@npmcli/agent": ["@npmcli/agent@4.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^11.2.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA=="],
|
||||
|
||||
"@npmcli/fs": ["@npmcli/fs@5.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og=="],
|
||||
|
||||
"@npmcli/redact": ["@npmcli/redact@4.0.0", "", {}, "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q=="],
|
||||
|
||||
"@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||
|
||||
"abbrev": ["abbrev@4.0.0", "", {}, "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA=="],
|
||||
|
||||
"agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
|
||||
|
||||
"balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
|
||||
|
||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||
|
||||
"bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
|
||||
|
||||
"brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="],
|
||||
|
||||
"buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
||||
|
||||
"cacache": ["cacache@20.0.4", "", { "dependencies": { "@npmcli/fs": "^5.0.0", "fs-minipass": "^3.0.0", "glob": "^13.0.0", "lru-cache": "^11.1.0", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^13.0.0" } }, "sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA=="],
|
||||
|
||||
"chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
|
||||
|
||||
"env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="],
|
||||
|
||||
"exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="],
|
||||
|
||||
"fast-xml-builder": ["fast-xml-builder@1.1.4", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="],
|
||||
|
||||
"fast-xml-parser": ["fast-xml-parser@5.6.0", "", { "dependencies": { "@nodable/entities": "^1.1.0", "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.5.0", "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-5G+uaEBbOm9M4dgMOV3K/rBzfUNGqGqoUTaYJM3hBwM8t71w07gxLQZoTsjkY8FtfjabqgQHEkeIySBDYeBmJw=="],
|
||||
|
||||
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" } }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||
|
||||
"fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
|
||||
|
||||
"fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="],
|
||||
|
||||
"glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
|
||||
|
||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||
|
||||
"http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="],
|
||||
|
||||
"http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
|
||||
|
||||
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
||||
|
||||
"iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
|
||||
|
||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||
|
||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||
|
||||
"ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="],
|
||||
|
||||
"isexe": ["isexe@4.0.0", "", {}, "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw=="],
|
||||
|
||||
"lru-cache": ["lru-cache@11.3.3", "", {}, "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ=="],
|
||||
|
||||
"make-fetch-happen": ["make-fetch-happen@15.0.5", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/agent": "^4.0.0", "@npmcli/redact": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", "ssri": "^13.0.0" } }, "sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg=="],
|
||||
|
||||
"minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="],
|
||||
|
||||
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
||||
|
||||
"minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
|
||||
|
||||
"minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="],
|
||||
|
||||
"minipass-fetch": ["minipass-fetch@5.0.2", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "optionalDependencies": { "iconv-lite": "^0.7.2" } }, "sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ=="],
|
||||
|
||||
"minipass-flush": ["minipass-flush@1.0.7", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA=="],
|
||||
|
||||
"minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="],
|
||||
|
||||
"minipass-sized": ["minipass-sized@2.0.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA=="],
|
||||
|
||||
"minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="],
|
||||
|
||||
"mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
||||
|
||||
"node-abi": ["node-abi@3.89.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA=="],
|
||||
|
||||
"node-addon-api": ["node-addon-api@8.7.0", "", {}, "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA=="],
|
||||
|
||||
"node-gyp": ["node-gyp@12.2.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^15.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "tar": "^7.5.4", "tinyglobby": "^0.2.12", "which": "^6.0.0" }, "bin": "bin/node-gyp.js" }, "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ=="],
|
||||
|
||||
"node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="],
|
||||
|
||||
"nopt": ["nopt@9.0.0", "", { "dependencies": { "abbrev": "^4.0.0" }, "bin": "bin/nopt.js" }, "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw=="],
|
||||
|
||||
"npm-run-path": ["npm-run-path@3.1.0", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg=="],
|
||||
|
||||
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
|
||||
|
||||
"p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="],
|
||||
|
||||
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
|
||||
|
||||
"path-expression-matcher": ["path-expression-matcher@1.5.0", "", {}, "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ=="],
|
||||
|
||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||
|
||||
"path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
|
||||
|
||||
"picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
|
||||
|
||||
"prebuildify": ["prebuildify@6.0.1", "", { "dependencies": { "minimist": "^1.2.5", "mkdirp-classic": "^0.5.3", "node-abi": "^3.3.0", "npm-run-path": "^3.1.0", "pump": "^3.0.0", "tar-fs": "^2.1.0" }, "bin": "bin.js" }, "sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw=="],
|
||||
|
||||
"prettier": ["prettier@3.8.2", "", { "bin": "bin/prettier.cjs" }, "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q=="],
|
||||
|
||||
"proc-log": ["proc-log@6.1.0", "", {}, "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ=="],
|
||||
|
||||
"pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="],
|
||||
|
||||
"readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||
|
||||
"rimraf": ["rimraf@6.1.3", "", { "dependencies": { "glob": "^13.0.3", "package-json-from-dist": "^1.0.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA=="],
|
||||
|
||||
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||
|
||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||
|
||||
"semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||
|
||||
"smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="],
|
||||
|
||||
"socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="],
|
||||
|
||||
"socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="],
|
||||
|
||||
"ssri": ["ssri@13.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ=="],
|
||||
|
||||
"string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
|
||||
|
||||
"strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="],
|
||||
|
||||
"tar": ["tar@7.5.13", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng=="],
|
||||
|
||||
"tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
|
||||
|
||||
"tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
|
||||
|
||||
"tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="],
|
||||
|
||||
"typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="],
|
||||
|
||||
"undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="],
|
||||
|
||||
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
||||
|
||||
"which": ["which@6.0.1", "", { "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" } }, "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg=="],
|
||||
|
||||
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
|
||||
|
||||
"yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
||||
|
||||
"minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||
|
||||
"minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||
|
||||
"tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
|
||||
|
||||
"minipass-flush/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
|
||||
|
||||
"minipass-pipeline/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
|
||||
}
|
||||
}
|
||||
10
lib/constants.ts
Normal file
10
lib/constants.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export const MwDEFAULT: number = 268435455;
|
||||
export const MwMB_ICONMASK: number = 15;
|
||||
export const MwMB_BUTTONMASK: number = 240;
|
||||
export const MwMB_BUTTONOK: number = 16;
|
||||
export const MwMB_BUTTONCANCEL: number = 32;
|
||||
export const MwMB_BUTTONYES: number = 64;
|
||||
export const MwMB_BUTTONNO: number = 128;
|
||||
export const MwKEY_FLAG: number = 2147483648;
|
||||
export const MwKEY_CONTROL_FLAG: number = 3221225472;
|
||||
export const MwKEY_ALT_FLAG: number = 2684354560;
|
||||
71
lib/enums.ts
Normal file
71
lib/enums.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
export enum MwDIRECTION {
|
||||
MwNORTH,
|
||||
MwSOUTH,
|
||||
MwEAST,
|
||||
MwWEST
|
||||
}
|
||||
|
||||
export enum MwORIENTATION {
|
||||
MwVERTICAL,
|
||||
MwHORIZONTAL
|
||||
}
|
||||
|
||||
export enum MwALIGNMENT {
|
||||
MwALIGNMENT_CENTER,
|
||||
MwALIGNMENT_BEGINNING,
|
||||
MwALIGNMENT_END
|
||||
}
|
||||
|
||||
export enum MwMB_ICON {
|
||||
MwMB_ICONWARNING = 1,
|
||||
MwMB_ICONINFO,
|
||||
MwMB_ICONNOTE,
|
||||
MwMB_ICONQUESTION,
|
||||
MwMB_ICONNEWS,
|
||||
MwMB_ICONERROR,
|
||||
MwMB_ICONCLOCK
|
||||
}
|
||||
|
||||
export enum MwCOORDINATE {
|
||||
MwCOORDINATE_GLOBAL,
|
||||
MwCOORDINATE_LOCAL
|
||||
}
|
||||
|
||||
export enum MwCLIPBOARD {
|
||||
MwCLIPBOARD_MAIN,
|
||||
MwCLIPBOARD_PRIMARY
|
||||
}
|
||||
|
||||
export enum MwMOUSE {
|
||||
MwMOUSE_LEFT = 1,
|
||||
MwMOUSE_MIDDLE,
|
||||
MwMOUSE_RIGHT,
|
||||
MwMOUSE_WHEELUP,
|
||||
MwMOUSE_WHEELDOWN
|
||||
}
|
||||
|
||||
export enum MwKEY {
|
||||
MwKEY_BACKSPACE = 2147483649,
|
||||
MwKEY_LEFT,
|
||||
MwKEY_RIGHT,
|
||||
MwKEY_UP,
|
||||
MwKEY_DOWN,
|
||||
MwKEY_ENTER,
|
||||
MwKEY_ESCAPE,
|
||||
MwKEY_LEFTSHIFT,
|
||||
MwKEY_RIGHTSHIFT,
|
||||
MwKEY_ALT,
|
||||
MwKEY_CONTROL
|
||||
}
|
||||
|
||||
export enum MwVULKANFIELD {
|
||||
MwVULKANFIELD_GETINSTANCEPROCADDR,
|
||||
MwVULKANFIELD_INSTANCE,
|
||||
MwVULKANFIELD_SURFACE,
|
||||
MwVULKANFIELD_PHYSICALDEVICE,
|
||||
MwVULKANFIELD_LOGICALDEVICE,
|
||||
MwVULKANFIELD_GRAPHICSQUEUEINDEX,
|
||||
MwVULKANFIELD_PRESENTQUEUEINDEX,
|
||||
MwVULKANFIELD_GRAPHICSQUEUE,
|
||||
MwVULKANFIELD_PRESENTQUEUE
|
||||
}
|
||||
0
lib/index.ts
Normal file
0
lib/index.ts
Normal file
32
lib/structs.ts
Normal file
32
lib/structs.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
export interface MwPoint {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
export interface MwRect {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export interface MwSizeHints {
|
||||
minWidth: number;
|
||||
minHeight: number;
|
||||
maxWidth: number;
|
||||
maxHeight: number;
|
||||
}
|
||||
|
||||
export interface MwRGB {
|
||||
red: number;
|
||||
green: number;
|
||||
blue: number;
|
||||
}
|
||||
|
||||
export interface MwMouse {}
|
||||
|
||||
export interface MwVulkanConfig {
|
||||
apiVersion: number;
|
||||
vkVersion: number;
|
||||
validationLayers: number;
|
||||
}
|
||||
56
package.json
Normal file
56
package.json
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"name": "milsko",
|
||||
"version": "1.0.1",
|
||||
"description": "Lightweight and cross-platform native GUI toolkit",
|
||||
"main": "lib/index.js",
|
||||
"type": "module",
|
||||
"upstream": "v1.0a",
|
||||
"scripts": {
|
||||
"bindgen": "node scripts/bindgen.js && prettier --write lib/",
|
||||
"download": "node scripts/download.js",
|
||||
"install": "node scripts/install.js",
|
||||
"update": "rimraf deps/milsko.tar.gz deps/milsko/ && node scripts/download.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://forgejo.nishi.boats/pyrite-dev/milsko-node.git"
|
||||
},
|
||||
"keywords": [
|
||||
"milsko",
|
||||
"ui",
|
||||
"gui",
|
||||
"desktop",
|
||||
"app"
|
||||
],
|
||||
"author": "PwLDev",
|
||||
"license": "BSD-3-Clause",
|
||||
"bugs": {
|
||||
"url": "https://forgejo.nishi.boats/pyrite-dev/milsko-node/issues"
|
||||
},
|
||||
"homepage": "https://forgejo.nishi.boats/pyrite-dev/milsko-node#readme",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^25.6.0",
|
||||
"fast-xml-parser": "^5.6.0",
|
||||
"node-gyp": "^12.2.0",
|
||||
"prebuildify": "^6.0.1",
|
||||
"prettier": "^3.8.2",
|
||||
"rimraf": "^6.1.3",
|
||||
"typescript": "^6.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-addon-api": "^8.7.0",
|
||||
"node-gyp-build": "^4.8.4",
|
||||
"tar": "^7.5.13"
|
||||
},
|
||||
"files": [
|
||||
"README.md",
|
||||
"package.json",
|
||||
"binding.gyp",
|
||||
"dist",
|
||||
"scripts",
|
||||
"prebuilds"
|
||||
]
|
||||
}
|
||||
163
scripts/bindgen.js
Normal file
163
scripts/bindgen.js
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
import { XMLParser } from "fast-xml-parser";
|
||||
import { createWriteStream } from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
|
||||
const { upstream } = createRequire(import.meta.url)("../package.json");
|
||||
const source =
|
||||
"https://forgejo.nishi.boats/api/v1/repos/pyrite-dev/milsko/tags";
|
||||
|
||||
// Out files
|
||||
const structsOut = createWriteStream("lib/structs.ts");
|
||||
const enumsOut = createWriteStream("lib/enums.ts");
|
||||
const constantsOut = createWriteStream("lib/constants.ts");
|
||||
|
||||
function toCamelCase(input) {
|
||||
const split = input.split("_");
|
||||
for (let i = 0; i < split.length; i++) {
|
||||
const firstChar =
|
||||
i <= 0
|
||||
? split[i].charAt(0).toLowerCase()
|
||||
: split[i].charAt(0).toUpperCase();
|
||||
|
||||
split[i] = firstChar + split[i].slice(1);
|
||||
}
|
||||
|
||||
return split.join("");
|
||||
}
|
||||
|
||||
function typeToTypescript(type) {
|
||||
switch (type) {
|
||||
case "integer":
|
||||
return "number";
|
||||
case "short":
|
||||
return "number";
|
||||
case "string":
|
||||
return "string";
|
||||
default:
|
||||
"any";
|
||||
}
|
||||
}
|
||||
|
||||
function scanStructs(root) {
|
||||
const list = root["structs"]["struct"];
|
||||
|
||||
for (const struct of list) {
|
||||
console.log(struct);
|
||||
const structName = struct["@_name"];
|
||||
structsOut.write("export interface " + structName + " {\n");
|
||||
|
||||
for (const [type, children] of Object.entries(struct)) {
|
||||
// attributes start with @_
|
||||
if (!type.startsWith("@_") && Array.isArray(children)) {
|
||||
for (const child of children) {
|
||||
const attributeName = toCamelCase(child["@_name"]);
|
||||
structsOut.write(
|
||||
attributeName + ": " + typeToTypescript(type) + ";\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
structsOut.write("}\n\n");
|
||||
}
|
||||
|
||||
structsOut.end();
|
||||
}
|
||||
|
||||
function scanEnumerations(root) {
|
||||
const list = root["enumerations"]["enumeration"];
|
||||
|
||||
for (const enumeration of list) {
|
||||
const enumName = enumeration["@_name"];
|
||||
enumsOut.write("export enum " + enumName + " {\n");
|
||||
|
||||
for (const [type, children] of Object.entries(enumeration)) {
|
||||
// attributes start with @_
|
||||
if (!type.startsWith("@_")) {
|
||||
for (const child of children) {
|
||||
const attributeName = child["@_name"];
|
||||
const attributeValue = child["#text"];
|
||||
|
||||
enumsOut.write(attributeName);
|
||||
if (attributeValue) enumsOut.write(" = " + attributeValue);
|
||||
|
||||
enumsOut.write(",\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enumsOut.write("}\n\n");
|
||||
}
|
||||
|
||||
enumsOut.end();
|
||||
}
|
||||
|
||||
function scanConstants(root) {
|
||||
const list = root["constants"];
|
||||
|
||||
for (const [type, children] of Object.entries(list)) {
|
||||
for (const child of children) {
|
||||
const constName = child["@_name"];
|
||||
const constValue = child["#text"];
|
||||
|
||||
constantsOut.write(
|
||||
"export const " +
|
||||
constName +
|
||||
": " +
|
||||
typeToTypescript(type) +
|
||||
" = " +
|
||||
constValue +
|
||||
";\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
constantsOut.end();
|
||||
}
|
||||
|
||||
async function bindgen() {
|
||||
const parser = new XMLParser({
|
||||
attributeNamePrefix: "@_",
|
||||
ignoreAttributes: false,
|
||||
parseAttributeValue: true
|
||||
});
|
||||
|
||||
const response = await fetch(source);
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
"Failed to fetch the Milsko repository tags, try running npm run install or npm run update again (" +
|
||||
response.status +
|
||||
")"
|
||||
);
|
||||
}
|
||||
|
||||
const tags = await response.json();
|
||||
const match = tags.find((k) => k.name == upstream);
|
||||
|
||||
if (!match) {
|
||||
throw new Error(
|
||||
"Could not find a tag that matches the upstream version " + upstream
|
||||
);
|
||||
}
|
||||
|
||||
const commitHash = match["id"]
|
||||
const specURL = "https://forgejo.nishi.boats/pyrite-dev/milsko/raw/commit/" +
|
||||
commitHash + "/milsko.xml";
|
||||
|
||||
const spac = await fetch(specURL);
|
||||
if (!spac.ok) {
|
||||
throw new Error(
|
||||
"Failed to fetch the XML API specification with status code " +
|
||||
spac.status
|
||||
);
|
||||
}
|
||||
|
||||
const raw = await spac.text();
|
||||
const root = parser.parse(raw)["milsko"];
|
||||
|
||||
scanStructs(root);
|
||||
scanEnumerations(root);
|
||||
scanConstants(root);
|
||||
}
|
||||
|
||||
bindgen();
|
||||
59
scripts/download.js
Normal file
59
scripts/download.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { execSync } from "node:child_process";
|
||||
import { createWriteStream, mkdirSync } from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import { join, resolve } from "node:path";
|
||||
import { Readable } from "node:stream";
|
||||
import { pipeline } from "node:stream/promises";
|
||||
import { t, extract as tarExtract } from "tar";
|
||||
|
||||
const extractDir = resolve("deps");
|
||||
const fileName = "milsko.tar.gz";
|
||||
const source =
|
||||
"https://forgejo.nishi.boats/api/v1/repos/pyrite-dev/milsko/tags";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const { upstream } = require("../package.json");
|
||||
|
||||
export async function download() {
|
||||
console.log("[Mw] Fetching Milsko release tags from", source);
|
||||
|
||||
const response = await fetch(source);
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
"Failed to fetch the Milsko repository tags, try running npm run install or npm run update again (" +
|
||||
response.status +
|
||||
")"
|
||||
);
|
||||
}
|
||||
|
||||
const tags = await response.json();
|
||||
const match = tags.find((k) => k.name == upstream);
|
||||
|
||||
if (!match) {
|
||||
throw new Error(
|
||||
"Could not find a tag that matches the upstream version " + upstream
|
||||
);
|
||||
}
|
||||
|
||||
const tarUrl = match["tarball_url"];
|
||||
console.log("[Mw] Fetching tarball from " + tarUrl);
|
||||
|
||||
const tarball = await fetch(tarUrl);
|
||||
|
||||
const filePath = join(extractDir, fileName);
|
||||
mkdirSync(extractDir, { recursive: true }); // mkdir -p
|
||||
|
||||
const tarStream = Readable.fromWeb(tarball.body);
|
||||
const fileStream = createWriteStream(filePath);
|
||||
|
||||
await pipeline(tarStream, fileStream);
|
||||
await tarExtract({
|
||||
file: filePath,
|
||||
cwd: extractDir
|
||||
});
|
||||
|
||||
console.log("[Mw] Milsko library successfully installed!");
|
||||
}
|
||||
|
||||
if (import.meta.main)
|
||||
download();
|
||||
31
scripts/install.js
Normal file
31
scripts/install.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { execSync } from "node:child_process"
|
||||
import { createRequire } from "node:module";
|
||||
import { download } from "./download";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const forceBuild = process.env["npm_config_build_from_source"] == "true";
|
||||
|
||||
function hasPrebuilt() {
|
||||
let prebuilt = false;
|
||||
|
||||
try {
|
||||
require("node-gyp-build")("..");
|
||||
prebuilt = true;
|
||||
} catch (error) {
|
||||
prebuilt = false;
|
||||
}
|
||||
|
||||
return prebuilt;
|
||||
}
|
||||
|
||||
async function install() {
|
||||
console.log("[Mw] Downloading Milsko library...");
|
||||
await download();
|
||||
|
||||
console.log("[Mw] Building from source...");
|
||||
execSync("npx node-gyp rebuild", { stdio: "inherit" });
|
||||
}
|
||||
|
||||
if (forceBuild || !hasPrebuilt()) {
|
||||
install();
|
||||
}
|
||||
0
src/classes.cpp
Normal file
0
src/classes.cpp
Normal file
4
src/classes.hpp
Normal file
4
src/classes.hpp
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include <napi.h>
|
||||
|
||||
Napi::Object ClassesInit(Napi::Env env, Napi::Object exports);
|
||||
13
src/milsko.cpp
Normal file
13
src/milsko.cpp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#include "widget.hpp"
|
||||
#include <Mw/Milsko.h>
|
||||
#include <napi.h>
|
||||
|
||||
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
||||
MwLibraryInit();
|
||||
|
||||
MwBaseWidget::Init(env, exports);
|
||||
|
||||
return exports;
|
||||
}
|
||||
|
||||
NODE_API_MODULE(milsko, Init);
|
||||
368
src/widget.cpp
Normal file
368
src/widget.cpp
Normal file
|
|
@ -0,0 +1,368 @@
|
|||
#include "widget.hpp"
|
||||
|
||||
Napi::FunctionReference MwBaseWidget::constructor;
|
||||
|
||||
Napi::Object MwBaseWidget::Init(Napi::Env env, Napi::Object exports) {
|
||||
Napi::HandleScope scope(env);
|
||||
Napi::Function func = DefineClass(env, "MwBaseWidget",
|
||||
{
|
||||
InstanceMethod("setArea", &SetArea),
|
||||
InstanceMethod("move", &Move),
|
||||
InstanceMethod("resize", &Resize),
|
||||
InstanceMethod("step", &Step),
|
||||
InstanceMethod("loop", &Loop),
|
||||
InstanceMethod("show", &Show),
|
||||
InstanceMethod("hideCursor", &HideCursor),
|
||||
InstanceMethod("grabPointer", &GrabPointer),
|
||||
InstanceMethod("getClipboard", &GetClipboard),
|
||||
InstanceMethod("addTickList", &AddTickList),
|
||||
InstanceMethod("forceRender", &ForceRender),
|
||||
InstanceMethod("reparent", &Reparent),
|
||||
InstanceMethod("add", &Add),
|
||||
InstanceMethod("remove", &Remove),
|
||||
InstanceAccessor("area", &GetArea, nullptr),
|
||||
InstanceAccessor("isPending", &IsPending, nullptr),
|
||||
InstanceAccessor("parent", &GetParent, nullptr),
|
||||
InstanceAccessor("children", &GetChildren, nullptr),
|
||||
InstanceAccessor("name", &GetName, nullptr),
|
||||
InstanceAccessor("cursorCoord", &GetCursorCoord, nullptr),
|
||||
InstanceAccessor("screenSize", &GetScreenSize, nullptr),
|
||||
InstanceAccessor("coordinateType", &GetCoordinateType, nullptr),
|
||||
});
|
||||
|
||||
constructor = Napi::Persistent(func);
|
||||
constructor.SuppressDestruct();
|
||||
|
||||
exports.Set("MwBaseWidget", func);
|
||||
return exports;
|
||||
};
|
||||
|
||||
MwBaseWidget::MwBaseWidget(const Napi::CallbackInfo &info):
|
||||
Napi::ObjectWrap<MwBaseWidget>(info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
|
||||
handle = MwCreateWidget(MwWindowClass, "window", nullptr, 0, 0, 300, 300);
|
||||
};
|
||||
|
||||
MwBaseWidget::~MwBaseWidget() {
|
||||
// call destructors for each children
|
||||
if (children.size() > 0) {
|
||||
for (const auto &child : children) {
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
|
||||
if (handle)
|
||||
MwDestroyWidget(handle);
|
||||
};
|
||||
|
||||
Napi::Value MwBaseWidget::GetArea(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object area = Napi::Object::New(env);
|
||||
|
||||
area.Set("x", Napi::Number::New(env, MwGetInteger(handle, MwNx)));
|
||||
area.Set("y", Napi::Number::New(env, MwGetInteger(handle, MwNy)));
|
||||
area.Set("width", Napi::Number::New(env, MwGetInteger(handle, MwNwidth)));
|
||||
area.Set("height", Napi::Number::New(env, MwGetInteger(handle, MwNheight)));
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::SetArea(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
if (info.Length() > 0 && info[0].IsObject()) {
|
||||
const Napi::Object rect = info[0].ToObject();
|
||||
|
||||
MwVaApply(handle,
|
||||
MwNx, rect.Has("x") ? rect.Get("x").As<Napi::Number>().Uint32Value() : 0,
|
||||
MwNy, rect.Has("y") ? rect.Get("y").As<Napi::Number>().Uint32Value() : 0,
|
||||
MwNwidth, rect.Has("width") ? rect.Get("width").As<Napi::Number>().Uint32Value() : 0,
|
||||
MwNheight, rect.Has("height") ? rect.Get("height").As<Napi::Number>().Uint32Value() : 0,
|
||||
nullptr
|
||||
);
|
||||
} else {
|
||||
Napi::TypeError::New(env, "Expected an object type of MwRect as argument")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
|
||||
return info.This();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::Move(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
if (info.Length() > 1 && info[0].IsNumber() && info[1].IsNumber()) {
|
||||
int x = info[0].As<Napi::Number>().Uint32Value();
|
||||
int y = info[1].As<Napi::Number>().Uint32Value();
|
||||
|
||||
MwVaApply(handle,
|
||||
MwNx, x,
|
||||
MwNy, y,
|
||||
nullptr
|
||||
);
|
||||
} else {
|
||||
Napi::TypeError::New(env, "Expected two number arguments (x, y)")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::Resize(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
if (info.Length() > 1 && info[0].IsNumber() && info[1].IsNumber()) {
|
||||
int width = info[0].As<Napi::Number>().Uint32Value();
|
||||
int height = info[1].As<Napi::Number>().Uint32Value();
|
||||
|
||||
MwVaApply(handle,
|
||||
MwNwidth, width,
|
||||
MwNheight, height,
|
||||
nullptr
|
||||
);
|
||||
} else {
|
||||
Napi::TypeError::New(env, "Expected two number arguments (width, height)")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::Step(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
int step = MwStep(handle);
|
||||
|
||||
return Napi::Boolean::New(env, step == 0);
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::IsPending(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
bool pending = MwPending(handle);
|
||||
|
||||
return Napi::Boolean::New(env, pending);
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::Loop(const Napi::CallbackInfo &info) {
|
||||
MwLoop(handle);
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::Show(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
bool toggle = true;
|
||||
|
||||
if (info.Length() > 0 && info[0].IsBoolean()) {
|
||||
toggle = info[0].As<Napi::Boolean>().Value();
|
||||
}
|
||||
|
||||
MwShow(handle, static_cast<int>(toggle));
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::HideCursor(const Napi::CallbackInfo &info) {
|
||||
MwHideCursor(handle);
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::GrabPointer(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
bool toggle = true;
|
||||
|
||||
if (info.Length() > 0 && info[0].IsBoolean()) {
|
||||
toggle = info[0].As<Napi::Boolean>().Value();
|
||||
}
|
||||
|
||||
MwGrabPointer(handle, static_cast<int>(toggle));
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::AddTickList(const Napi::CallbackInfo &info) {
|
||||
MwAddTickList(handle);
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::ForceRender(const Napi::CallbackInfo &info) {
|
||||
MwForceRender(handle);
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::Reparent(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
if (info.Length() < 1 || !info[0].IsObject() || !info[0].IsNull()) {
|
||||
Napi::TypeError::New(env, "Expected an instance of a widget class as argument")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
MwBaseWidget *newParent = nullptr;
|
||||
|
||||
if (info[0].IsObject()) {
|
||||
Napi::Object wrapped = info[0].As<Napi::Object>();
|
||||
const bool isInstance = wrapped.InstanceOf(constructor.Value());
|
||||
|
||||
if (!isInstance) {
|
||||
Napi::TypeError::New(env, "Provided argument is not an instance of a widget")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
newParent = MwBaseWidget::Unwrap(wrapped);
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
// if the current parent has this widget as a child, disown :(
|
||||
for (size_t i = 0; i < parent->children.size(); i++) {
|
||||
if (parent->children[i] == this) {
|
||||
parent->children.erase(parent->children.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MwReparent(
|
||||
handle,
|
||||
newParent ? newParent->handle : nullptr
|
||||
);
|
||||
|
||||
parent = newParent;
|
||||
newParent->children.push_back(this);
|
||||
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::Add(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
if (info.Length() < 1 || !info[0].IsObject()) {
|
||||
Napi::TypeError::New(env, "Expected an instance of a widget class as argument")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Undefined();
|
||||
}
|
||||
|
||||
Napi::Object wrapped = info[0].As<Napi::Object>();
|
||||
const bool isInstance = wrapped.InstanceOf(constructor.Value());
|
||||
|
||||
if (isInstance) {
|
||||
MwBaseWidget *child = MwBaseWidget::Unwrap(wrapped);
|
||||
|
||||
if (child == this) {
|
||||
Napi::Error::New(env, "Cannot add widget as child of itself")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
if (child->parent) {
|
||||
// if the current parent has this widget as a child, disown :(
|
||||
for (int i = 0; i < child->parent->children.size(); i++) {
|
||||
if (child->parent->children[i] == this) {
|
||||
child->parent->children.erase(child->parent->children.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MwReparent(
|
||||
child->handle,
|
||||
handle
|
||||
);
|
||||
|
||||
child->parent = this;
|
||||
children.push_back(child);
|
||||
} else {
|
||||
Napi::TypeError::New(env, "Provided argument is not an instance of a widget")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::Remove(const Napi::CallbackInfo &info) {
|
||||
if (parent) {
|
||||
for (size_t i = 0; i < parent->children.size(); i++) {
|
||||
if (parent->children[i] == this) {
|
||||
parent->children.erase(parent->children.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MwReparent(handle, nullptr);
|
||||
return Napi::Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::GetParent(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
if (!parent)
|
||||
return env.Null();
|
||||
|
||||
return parent->Value();
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::GetChildren(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Array result = Napi::Array::New(env, children.size());
|
||||
|
||||
for (size_t i = 0; i < children.size(); i++) {
|
||||
result.Set(i, children[i]->Value());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::GetName(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
const std::string name = MwGetName(handle);
|
||||
|
||||
return Napi::String::New(env, name);
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::GetCursorCoord(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object coord = Napi::Object::New(env);
|
||||
MwPoint point;
|
||||
|
||||
MwGetCursorCoord(handle, &point);
|
||||
coord.Set("x", Napi::Number::New(env, point.x));
|
||||
coord.Set("y", Napi::Number::New(env, point.y));
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::GetScreenSize(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object size = Napi::Object::New(env);
|
||||
MwRect rect;
|
||||
|
||||
MwGetScreenSize(handle, &rect);
|
||||
size.Set("x", Napi::Number::New(env, rect.x));
|
||||
size.Set("y", Napi::Number::New(env, rect.y));
|
||||
size.Set("width", Napi::Number::New(env, rect.width));
|
||||
size.Set("height", Napi::Number::New(env, rect.height));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::GetCoordinateType(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
int coordType = MwGetCoordinateType(handle);
|
||||
|
||||
return Napi::Number::New(env, coordType);
|
||||
}
|
||||
|
||||
Napi::Value MwBaseWidget::GetClipboard(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
if (info.Length() > 0 && info[0].IsNumber()) {
|
||||
int type = info[0].As<Napi::Number>().Uint32Value();
|
||||
MwGetClipboard(handle, type);
|
||||
} else {
|
||||
Napi::TypeError::New(env, "Expected a clipboard type number argument.")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
|
||||
return env.Undefined();
|
||||
}
|
||||
42
src/widget.hpp
Normal file
42
src/widget.hpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
#include <Mw/Milsko.h>
|
||||
#include <napi.h>
|
||||
#include <vector>
|
||||
|
||||
class MwBaseWidget : public Napi::ObjectWrap<MwBaseWidget> {
|
||||
public:
|
||||
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
||||
MwBaseWidget(const Napi::CallbackInfo &info);
|
||||
~MwBaseWidget();
|
||||
|
||||
protected:
|
||||
static Napi::FunctionReference constructor;
|
||||
|
||||
MwWidget handle;
|
||||
MwBaseWidget *parent;
|
||||
std::vector<MwBaseWidget *> children;
|
||||
|
||||
Napi::Value SetArea(const Napi::CallbackInfo &info);
|
||||
Napi::Value Move(const Napi::CallbackInfo &info);
|
||||
Napi::Value Resize(const Napi::CallbackInfo &info);
|
||||
Napi::Value Step(const Napi::CallbackInfo &info);
|
||||
Napi::Value Loop(const Napi::CallbackInfo &info);
|
||||
Napi::Value Show(const Napi::CallbackInfo &info);
|
||||
Napi::Value HideCursor(const Napi::CallbackInfo &info);
|
||||
Napi::Value GrabPointer(const Napi::CallbackInfo &info);
|
||||
Napi::Value AddTickList(const Napi::CallbackInfo &info);
|
||||
Napi::Value ForceRender(const Napi::CallbackInfo &info);
|
||||
Napi::Value Reparent(const Napi::CallbackInfo &info);
|
||||
Napi::Value Add(const Napi::CallbackInfo &info);
|
||||
Napi::Value Remove(const Napi::CallbackInfo &info);
|
||||
Napi::Value GetClipboard(const Napi::CallbackInfo &info);
|
||||
|
||||
Napi::Value GetArea(const Napi::CallbackInfo &info);
|
||||
Napi::Value IsPending(const Napi::CallbackInfo &info);
|
||||
Napi::Value GetParent(const Napi::CallbackInfo &info);
|
||||
Napi::Value GetChildren(const Napi::CallbackInfo &info);
|
||||
Napi::Value GetName(const Napi::CallbackInfo &info);
|
||||
Napi::Value GetCursorCoord(const Napi::CallbackInfo &info);
|
||||
Napi::Value GetScreenSize(const Napi::CallbackInfo &info);
|
||||
Napi::Value GetCoordinateType(const Napi::CallbackInfo &info);
|
||||
};
|
||||
19
tsconfig.json
Normal file
19
tsconfig.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"rootDir": "./lib",
|
||||
"outDir": "./dist",
|
||||
"module": "es2020",
|
||||
"target": "esnext",
|
||||
"types": ["node"],
|
||||
"allowJs": true,
|
||||
"declaration": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"noImplicitReturns": true,
|
||||
"strict": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noUncheckedSideEffectImports": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"exclude": ["scripts"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue