This commit is contained in:
Simon Cambier 2026-01-17 10:09:43 +01:00
parent 4bff6127b0
commit 431498fffa
7 changed files with 940 additions and 56 deletions

7
.prettierrc.json Normal file
View File

@ -0,0 +1,7 @@
{
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 100
}

View File

@ -2,7 +2,11 @@
This is an experimental template project to mix-and-match TypeScript and Lua for your Picotron projects.
Most of the _G.d.ts file has been AI-generated from the official documentation.
Most of the _G.d.ts file has been AI-generated from the official documentation, with progressive manual adjustments.
> [!IMPORTANT]
> TypeScript code converted to Lua code is not guaranteed to be correct or efficient.
> Read the [TypeScriptToLua documentation](https://typescripttolua.github.io/docs/getting-started), follow best practices, and review the generated Lua code.
## Setup

164
_G.d.ts vendored
View File

@ -1,3 +1,4 @@
/* eslint-disable */
// Picotron v0.2.1e Global API Type Definitions
// =====================
@ -282,6 +283,16 @@ declare function color(c: number): void
declare function pal(c0?: number, c1?: number, p?: number): void
declare function palt(c?: number, t?: boolean): void
declare function fillp(pattern?: number): void
declare function fillp(
a: number,
b: number,
c: number,
d: number,
e: number,
f: number,
g: number,
h: number
): void
declare function pget(x: number, y: number): number
declare function pset(x: number, y: number, c?: number): void
declare function cursor(x?: number, y?: number, c?: number): void
@ -461,15 +472,14 @@ declare function apply_delta(str0: string, delta: string): string | null
// =====================
// Tables API
// =====================
declare function add(t: any[], item: any, index?: number): void
declare function del(t: any[], item: any): void
declare function deli(t: any[], index: number): any
declare function add<T>(t: T[], item: T, index?: number): void
declare function del<T>(t: T[], item: T): void
declare function deli<T>(t: T[], index: number): T
declare function count(t: any[]): number
declare function all(t: any[]): () => any | undefined
declare function foreach(t: any[], fn: (item: any) => void): void
declare function pairs(
t: any
): LuaMultiReturn<[(t: any, k?: any) => LuaMultiReturn<[any, any]>, any, any]>
declare function foreach<T>(t: T[], fn: (item: T) => void): void
declare function all<T>(t: T[]): LuaIterable<T>
declare function pairs<T>(t: T[]): LuaIterable<LuaMultiReturn<[string, T]>>
declare function ipairs<T>(t: T[]): LuaIterable<LuaMultiReturn<[number, T]>>
declare function next(t: any, k?: any): LuaMultiReturn<[any, any]>
// =====================
@ -629,6 +639,8 @@ declare function window(
squashable: boolean
background_updates: boolean
background_draws: boolean
capture_escapes: boolean
fullscreen: boolean
}>
): any
declare function window(width: number, height: number): any
@ -688,8 +700,9 @@ interface GuiMsg {
propagate_to_children?: boolean
}
// Properties that can be passed when creating/attaching elements
// Base attributes for all elements
interface GuiElementAttribs {
// Position and size
x?: number
y?: number
z?: number
@ -697,13 +710,13 @@ interface GuiElementAttribs {
height?: number
width0?: number
height0?: number
// Relative sizing
width_rel?: number
height_rel?: number
width_add?: number
height_add?: number
// Layout
justify?: 'left' | 'center' | 'right'
vjustify?: 'top' | 'center' | 'bottom'
@ -714,31 +727,15 @@ interface GuiElementAttribs {
squash_to_parent?: boolean
min_width?: number
min_height?: number
// Appearance
label?: string
cursor?: string | number
bgcol?: number
fgcol?: number
border?: number
highlight?: boolean
hidden?: boolean
ghost?: boolean
// Custom properties
action?: (this: GuiElement) => void
divider?: boolean
icon?: number | Userdata
shortcut?: string
stay_open?: boolean
autohide?: boolean
// For fields
get?: (this: GuiElement) => string
set?: (this: GuiElement, val: string) => void
print_prefix?: string
str?: string
[key: string]: unknown
// Event handlers
click?: (this: GuiElement, msg: GuiMsg) => boolean | void
doubleclick?: (this: GuiElement, msg: GuiMsg) => boolean | void
@ -748,11 +745,66 @@ interface GuiElementAttribs {
tap?: (this: GuiElement, msg: GuiMsg) => boolean | void
mousewheel?: (this: GuiElement, msg: GuiMsg) => boolean | void
hover?: (this: GuiElement, msg: GuiMsg) => boolean | void
drag_items?: (this: GuiElement, msg: GuiMsg) => boolean | void
drop_items?: (this: GuiElement, msg: GuiMsg) => boolean | void
update?: (this: GuiElement, msg: GuiMsg) => boolean | void
draw?: (this: GuiElement, msg: GuiMsg) => void
test_point?: (this: GuiElement, x: number, y: number) => boolean
}
// Button element
interface GuiButtonAttribs extends GuiElementAttribs {
label?: string
fgcol?: number
bgcol?: number
border?: number
}
// Pulldown element
interface GuiPulldownAttribs extends GuiElementAttribs {
onclose?: (this: GuiElement) => void
}
// Pulldown item
interface GuiPulldownItemAttribs extends GuiElementAttribs {
label?: string
action?: (this: GuiElement) => void
shortcut?: string
stay_open?: boolean
divider?: boolean
}
// Scrollbar element
interface GuiScrollbarAttribs extends GuiElementAttribs {
bgcol?: number
fgcol?: number
autohide?: boolean
}
// Text editor element
interface GuiTextEditorAttribs extends GuiElementAttribs {
show_line_numbers?: boolean
embed_pods?: boolean
syntax_highlighting?: boolean
show_tabs?: boolean
max_lines?: number
has_search?: boolean
bgcol?: number
fgcol?: number
curcol?: number
selcol?: number
lncol?: number
block_scrolling?: boolean
key_callback?:
| Record<string, (this: GuiElement, k: string) => boolean | void>
| ((this: GuiElement, k: string) => boolean | void)
text_callback?:
| Record<string, (this: GuiElement, txt: string) => boolean | void>
| ((this: GuiElement, txt: string) => boolean | void)
margin_top?: number
margin_left?: number
}
interface GuiElement extends GuiElementAttribs {
// Always exist after creation (set by GuiElement:new)
z: number
@ -761,35 +813,32 @@ interface GuiElement extends GuiElementAttribs {
clip_to_parent: boolean
child: GuiElement[]
t0: number
// Set during attach
parent?: GuiElement
head: Gui
// Click tracking (set by gui internally)
last_click_t?: number
last_click_mb?: number
last_tap_t?: number
last_tap_mb?: number
// Methods
attach<T extends GuiElementAttribs & Record<string, unknown>>(
child?: T
): GuiElement & T
attach_button<T extends GuiElementAttribs & Record<string, unknown>>(
el: T
): GuiElement & T & { label: string; width: number; height: number; cursor: string; bgcol: number; fgcol: number; border: number }
attach_pulldown<T extends GuiElementAttribs & Record<string, unknown>>(
el: T
): GuiElement & T & { item_y: number; item_h: number }
attach_pulldown_item<T extends GuiElementAttribs & Record<string, unknown>>(
el: T
): GuiElement & T & { label: string; x: number; y: number; width: number; height: number }
attach_field<T extends GuiElementAttribs & Record<string, unknown>>(
attach<T extends GuiElementAttribs & Record<string, unknown>>(child?: T): GuiElement & T
attach_button<T extends GuiButtonAttribs & Record<string, unknown>>(el?: T): GuiElement & T
attach_pulldown<T extends GuiPulldownAttribs & Record<string, unknown>>(el?: T): GuiElement & T
attach_pulldown_item<T extends GuiPulldownItemAttribs & Record<string, unknown>>(
el: T
): GuiElement & T
attach_scrollbars(attribs?: { autohide?: boolean }): GuiElement
attach_text_editor(...args: any[]): GuiElement
attach_field<T extends GuiElementAttribs & Record<string, unknown>>(el?: T): GuiElement & T
attach_scrollbars(attribs?: GuiScrollbarAttribs): GuiElement
attach_text_editor(el?: GuiTextEditorAttribs): GuiElement & {
get_text(): string[]
set_text(text: string[] | string): void
get_cursor(): LuaMultiReturn<[number, number]>
set_cursor(x: number, y: number): void
}
detach(el?: GuiElement): GuiElement | void
bring_to_front(): void
push_to_back(): void
@ -804,22 +853,33 @@ interface Gui extends GuiElement {
y: number
width: number
height: number
pointer_element?: GuiElement
keyboard_focus_el?: GuiElement
mouse_cursor_gfx?: string | number | false
update_all(): void
draw_all(): void
get_pointer_element(): GuiElement | undefined
get_keyboard_focus_element(): GuiElement | undefined
el_at_xy(x: number, y: number): GuiElement | undefined
el_at_pointer(x: number, y: number): GuiElement | undefined
new<T extends GuiElementAttribs & Record<string, unknown>>(el: T): GuiElement & T
new <T extends GuiElementAttribs & Record<string, unknown>>(el: T): GuiElement & T
}
declare function create_gui(head_el?: GuiElementAttribs): Gui
interface GuiMenuItemAttribs {
id?: string
label?: string | (() => string)
shortcut?: string
action?: () => void
stay_open?: boolean
divider?: boolean
}
declare function menuitem(attribs?: GuiMenuItemAttribs): void
// =====================
// Main Loop Callbacks
// =====================

37
eslint.config.mts Normal file
View File

@ -0,0 +1,37 @@
import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
plugins: { js },
extends: ["js/recommended"],
languageOptions: { globals: globals.browser },
},
// Presets
...tseslint.configs.recommended,
// Overrides
{
files: ["**/*.ts"],
rules: {
"no-restricted-syntax": [
"warn",
{
selector: "CallExpression[callee.property.name='splice']",
message:
"For deleting a single item, prefer using `(deli(array, index+1)` from Picotron's api.",
},
],
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": [
"warn",
{ argsIgnorePattern: "^_" },
],
"@typescript-eslint/strict-boolean-expressions": "error",
},
},
]);

View File

@ -5,10 +5,17 @@
"dev": "pnpm check && tstl --watch"
},
"devDependencies": {
"@eslint/js": "^9.39.2",
"@typescript-eslint/eslint-plugin": "^8.52.0",
"@typescript-eslint/parser": "^8.52.0",
"@typescript-to-lua/language-extensions": "^1.19.0",
"eslint": "^9.39.2",
"globals": "^17.0.0",
"jiti": "^2.6.1",
"madge": "^8.0.0",
"prettier": "^3.7.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.53.0",
"typescript-to-lua": "^1.33.0"
},
"madge": {

File diff suppressed because it is too large Load Diff

View File

@ -6,13 +6,14 @@
"moduleResolution": "Node",
"types": ["@typescript-to-lua/language-extensions"],
"strict": true,
"outDir": "build"
"outDir": "build",
"allowSyntheticDefaultImports": true,
},
"tstl": {
"luaTarget": "5.4",
"noImplicitSelf": true,
"luaLibImport": "require-minimal",
"luaBundleEntry": "src/main.ts",
"luaBundle": "bundle.lua"
}
"luaBundle": "bundle.lua",
},
}