improve gui bindings

This commit is contained in:
Alexander Klingenbeck 2023-06-03 09:15:38 +02:00
parent 13f74bf5a1
commit 090b507bdd
9 changed files with 201 additions and 124 deletions

View File

@ -360,6 +360,7 @@ function main(){
getFunction(api.functions, "SaveFileData")!.binding = { }
ignore("ExportDataAsCode")
getFunction(api.functions, "LoadFileText")!.binding = { after: gen => gen.call("UnloadFileText", ["returnVal"]) }
getFunction(api.functions, "SaveFileText")!.params![1].binding = { typeAlias: "const char *" }
ignore("UnloadFileText")
const createFileList = (gen: QuickJsGenerator, loadName: string, unloadName: string, args: string[]) => {
@ -496,14 +497,30 @@ function main(){
core.exportGlobalConstant("DEG2RAD", "(PI/180.0)")
core.exportGlobalConstant("RAD2DEG", "(180.0/PI)")
ignore("GuiDropdownBox")
ignore("GuiSpinner")
ignore("GuiValueBox")
ignore("GuiListView")
const setOutParam = (fun: RayLibFunction, index: number) => {
const param = fun!.params![index]
param.binding = {
jsType: `{ ${param.name}: number }`,
customConverter: gen => {
gen.declare(param.name+"_out", param.type.replace(" *",""))
gen.declare(param.name, param.type, false, "&"+param.name+"_out")
},
customCleanup: gen => {
gen.call("JS_SetPropertyStr", ["ctx", "argv["+index+"]", `"${param.name}"`, "JS_NewInt32(ctx,"+param.name+"_out)"])
}
}
}
setOutParam(getFunction(api.functions, "GuiDropdownBox")!, 2)
setOutParam(getFunction(api.functions, "GuiSpinner")!, 2)
setOutParam(getFunction(api.functions, "GuiValueBox")!, 2)
setOutParam(getFunction(api.functions, "GuiListView")!, 2)
ignore("GuiListViewEx")
ignore("GuiTextBox")
ignore("GuiTextInputBox")
ignore("GuiGetIcons")
//setOutParam(getFunction(api.functions, "GuiTextInputBox")!, 6)
ignore("GuiTabBar")
ignore("GuiGetIcons")
ignore("GuiLoadIcons")
// TODO: Parse and support light struct
ignore("CreateLight")

View File

@ -20,7 +20,11 @@ export interface FuncBindingOptions {
}
export interface ParamBindingOptions {
ignore?: boolean
ignore?: boolean,
customConverter?: (gen: QuickJsGenerator) => void,
customCleanup?: (gen: QuickJsGenerator) => void,
jsType?: string,
typeAlias?: string
}
export type RayLibType = "void" | "const char *" | "bool" | "float" | "unsigned char" | "void *" | "int" | "usigned int" | "Texture" | "Rectangle" | "Image" | "Rectangle *" | "GylphInfo *" | "Texture2D" | "Vector3" | "Vector2" | "float *" | "unsigned char *" | "unsigned short *" | "unsigned int *" | "Shader" | "MaterialMap *" | "float[4]" | "Vector3"

View File

@ -1,5 +1,4 @@
import { writeFileSync } from "fs";
import { ApiFunction } from "./api"
import { CodeGenerator, CodeWriter, FunctionArgument, GenericCodeGenerator } from "./generation"
export type StructLookup = { [struct: string]: string }
@ -76,8 +75,8 @@ export abstract class GenericQuickJsGenerator<T extends QuickJsGenerator> extend
return sub
}
jsToC(type: string, name: string, src: string, classIds: StructLookup = {}, supressDeclaration = false){
switch (type) {
jsToC(type: string, name: string, src: string, classIds: StructLookup = {}, supressDeclaration = false, typeAlias?: string){
switch (typeAlias ?? type) {
// Array Buffer
case "const void *":
case "void *":
@ -93,7 +92,7 @@ export abstract class GenericQuickJsGenerator<T extends QuickJsGenerator> extend
break;
// String
case "const char *":
case "char *":
//case "char *":
if(!supressDeclaration) this.statement(`${type} ${name} = (${type})JS_ToCString(ctx, ${src})`)
else this.statement(`${name} = (${type})JS_ToCString(ctx, ${src})`)
break;
@ -125,7 +124,6 @@ export abstract class GenericQuickJsGenerator<T extends QuickJsGenerator> extend
if(!supressDeclaration) this.statement(`${type} ${name} = JS_ToBool(ctx, ${src})`)
else this.statement(`${name} = JS_ToBool(ctx, ${src})`)
break;
// Structs / Struct *
default:
const isConst = type.startsWith('const')
const isPointer = type.endsWith(' *')

View File

@ -34,13 +34,15 @@ export class RayLibHeader extends QuickJsHeader {
for (let i = 0; i < api.params.length; i++) {
if(api.params[i]?.binding?.ignore) continue;
const para = api.params[i]
fun.jsToC(para.type,para.name,"argv["+i+"]", this.structLookup)
if(para.binding?.customConverter) para.binding.customConverter(fun)
else fun.jsToC(para.type,para.name,"argv["+i+"]", this.structLookup, false, para.binding?.typeAlias)
}
// call c function
if(options.customizeCall) fun.line(options.customizeCall)
else fun.call(api.name, api.params.map(x => x.name), api.returnType === "void" ? null : {type: api.returnType, name: "returnVal"})
// clean up parameters
for (const param of api.params) {
if(param.binding?.customCleanup) param.binding.customCleanup(fun)
fun.jsCleanUpParameter(param.type, param.name)
}
// return result

View File

@ -18,7 +18,7 @@ export class TypeScriptDeclaration {
addFunction(name: string, api: RayLibFunction){
const options = api.binding || {}
const para = (api.params || []).filter(x => !x.binding?.ignore).map(x => ({ name: x.name, type: this.toJsType(x.type)}))
const para = (api.params || []).filter(x => !x.binding?.ignore).map(x => ({ name: x.name, type: x.binding?.jsType ?? this.toJsType(x.type)}))
const returnType = options.jsReturns ?? this.toJsType(api.returnType)
this.functions.tsDeclareFunction(name, para, returnType, api.description)
}

View File

@ -1478,8 +1478,12 @@ declare function guiToggleGroup(bounds: Rectangle, text: string, active: number)
declare function guiCheckBox(bounds: Rectangle, text: string, checked: boolean): boolean;
/** Combo Box control, returns selected item index */
declare function guiComboBox(bounds: Rectangle, text: string, active: number): number;
/** Text Box control, updates input text */
declare function guiTextBox(bounds: Rectangle, text: string, textSize: number, editMode: boolean): boolean;
/** Dropdown Box control, returns selected item */
declare function guiDropdownBox(bounds: Rectangle, text: string, active: { active: number }, editMode: boolean): boolean;
/** Spinner control, returns selected value */
declare function guiSpinner(bounds: Rectangle, text: string, value: { value: number }, minValue: number, maxValue: number, editMode: boolean): boolean;
/** Value Box control, updates input text with numbers */
declare function guiValueBox(bounds: Rectangle, text: string, value: { value: number }, minValue: number, maxValue: number, editMode: boolean): boolean;
/** Slider control, returns selected value */
declare function guiSlider(bounds: Rectangle, textLeft: string, textRight: string, value: number, minValue: number, maxValue: number): number;
/** Slider Bar control, returns selected value */
@ -1492,6 +1496,8 @@ declare function guiStatusBar(bounds: Rectangle, text: string): void;
declare function guiDummyRec(bounds: Rectangle, text: string): void;
/** Grid control, returns mouse cell position */
declare function guiGrid(bounds: Rectangle, text: string, spacing: number, subdivs: number): Vector2;
/** List View control, returns selected list item index */
declare function guiListView(bounds: Rectangle, text: string, scrollIndex: { scrollIndex: number }, active: number): number;
/** Message Box control, displays a message */
declare function guiMessageBox(bounds: Rectangle, title: string, message: string, buttons: string): number;
/** Color Picker control (multiple color controls) */

View File

@ -1,55 +1,29 @@
/*******************************************************************************************
*
* raygui - controls test suite
*
* TEST CONTROLS:
* - GuiDropdownBox()
* - GuiCheckBox()
* - GuiSpinner()
* - GuiValueBox()
* - GuiTextBox()
* - GuiButton()
* - GuiComboBox()
* - GuiListView()
* - GuiToggleGroup()
* - GuiColorPicker()
* - GuiSlider()
* - GuiSliderBar()
* - GuiProgressBar()
* - GuiColorBarAlpha()
* - GuiScrollPanel()
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2016-2023 Ramon Santamaria (@raysan5)
*
**********************************************************************************************/
// Initialization
//--------------------------------------------------------------------------------------
const screenWidth = 690;
const screenHeight = 560;
//---------------------------------------------------------------------------------------
let screenWidth = 690;
let screenHeight = 560;
initWindow(screenWidth, screenHeight, "raygui - controls test suite");
setExitKey(0);
// GUI controls initialization
//----------------------------------------------------------------------------------
let dropdownBox000Active = 0;
let dropdownBox000Active = {active: 0};
let dropDown000EditMode = false;
let dropdownBox001Active = 0;
let dropdownBox001Active = {active:0};
let dropDown001EditMode = false;
let spinner001Value = 0;
let spinner001Value = { value: 0 };
let spinnerEditMode = false;
let valueBox002Value = 0;
let valueBox002Value = { value: 0 };
let valueBoxEditMode = false;
let textBoxText = "Text box";
let textBoxEditMode = false;
let listViewScrollIndex = 0;
let listViewScrollIndex = { scrollIndex: 0 };
let listViewActive = -1;
let listViewExScrollIndex = 0;
@ -61,7 +35,7 @@ let multiTextBoxText = "Multi text box";
let multiTextBoxEditMode = false;
let colorPickerValue = RED;
let sliderValue = 50.0;
let sliderValue = 50;
let sliderBarValue = 60;
let progressValue = 0.4;
@ -73,20 +47,20 @@ let comboBoxActive = 1;
let toggleGroupActive = 0;
let viewScroll = new Vector2(0, 0);
let viewScroll = new Vector2(0,0);
//----------------------------------------------------------------------------------
// Custom GUI font loading
//Font font = LoadFontEx("fonts/rainyhearts16.ttf", 12, 0, 0);
//GuiSetFont(font);
//let font = loadFontEx("fonts/rainyhearts16.ttf", 12, 0, 0);
//guiSetFont(font);
let exitWindow = false;
let showMessageBox = false;
let textInput = new Array(256).fill(0);
let textInput = "";
let showTextInputBox = false;
let textInputFileName = new Array(256).fill(0);
let textInputFileName = "";
setTargetFPS(60);
//--------------------------------------------------------------------------------------
@ -104,9 +78,9 @@ while (!exitWindow) // Detect window close button or ESC key
if (isFileDropped())
{
const droppedFiles = loadDroppedFiles();
let droppedFiles = loadDroppedFiles();
if ((droppedFiles.length > 0) && isFileExtension(droppedFiles[0], ".rgs")) guiLoadStyle(droppedFiles.paths[0]);
if ((droppedFiles.length > 0) && isFileExtension(droppedFiles[0], ".rgs")) guiLoadStyle(droppedFiles[0]);
}
//----------------------------------------------------------------------------------
@ -123,99 +97,97 @@ while (!exitWindow) // Detect window close button or ESC key
dropDown001EditMode) guiLock();
// First GUI column
guiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
forceSquareChecked = guiCheckBox(new Rectangle(25, 108, 15, 15), "FORCE CHECK!", forceSquaredChecked);
//guiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
forceSquaredChecked = guiCheckBox(new Rectangle(25, 108, 15, 15), "FORCE CHECK!", forceSquaredChecked);
guiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
guiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
if (guiSpinner(new Rectangle(25, 135, 125, 30), NULL, &spinner001Value, 0, 100, spinnerEditMode)) spinnerEditMode = !spinnerEditMode;
//if (guiValueBox(new Rectangle(25, 175, 125, 30), NULL, &valueBox002Value, 0, 100, valueBoxEditMode)) valueBoxEditMode = !valueBoxEditMode;
//guiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
if (guiSpinner(new Rectangle(25, 135, 125, 30), null, spinner001Value, 0, 100, spinnerEditMode)) spinnerEditMode = !spinnerEditMode;
if (guiValueBox(new Rectangle(25, 175, 125, 30), null, valueBox002Value, 0, 100, valueBoxEditMode)) valueBoxEditMode = !valueBoxEditMode;
guiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
if (guiTextBox(new Rectangle(25, 215, 125, 30), textBoxText, 64, textBoxEditMode)) textBoxEditMode = !textBoxEditMode;
//if (guiTextBox(new Rectangle(25, 215, 125, 30), textBoxText, 64, textBoxEditMode)) textBoxEditMode = !textBoxEditMode;
guiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
if (guiButton(new Rectangle( 25, 255, 125, 30 ), guiIconText(ICON_FILE_SAVE, "Save File"))) showTextInputBox = true;
if (guiButton(new Rectangle(25, 255, 125, 30), guiIconText(ICON_FILE_SAVE, "Save File"))) showTextInputBox = true;
guiGroupBox(Rectangle( 25, 310, 125, 150 ), "STATES");
//GuiLock();
guiGroupBox(new Rectangle(25, 310, 125, 150), "STATES");
//guiLock();
guiSetState(STATE_NORMAL); if (guiButton(new Rectangle(30, 320, 115, 30), "NORMAL")) { }
guiSetState(STATE_FOCUSED); if (guiButton(new Rectangle(30, 355, 115, 30), "FOCUSED")) { }
guiSetState(STATE_PRESSED); if (guiButton(new Rectangle(30, 390, 115, 30), "#15#PRESSED")) { }
guiSetState(STATE_DISABLED); if (guiButton(new Rectangle(30, 425, 115, 30), "DISABLED")) { }
guiSetState(STATE_NORMAL);
//GuiUnlock();
//guiUnlock();
comboBoxActive = guiComboBox(new Rectangle(25, 470, 125, 30), "ONE;TWO;THREE;FOUR", comboBoxActive);
// NOTE: GuiDropdownBox must draw after any other control that can be covered on unfolding
GuiUnlock();
GuiSetStyle(DROPDOWNBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
if (GuiDropdownBox(new Rectangle(25, 65, 125, 30), "#01#ONE;#02#TWO;#03#THREE;#04#FOUR", &dropdownBox001Active, dropDown001EditMode)) dropDown001EditMode = !dropDown001EditMode;
guiUnlock();
guiSetStyle(DROPDOWNBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
if (guiDropdownBox(new Rectangle(25, 65, 125, 30), "#01#ONE;#02#TWO;#03#THREE;#04#FOUR", dropdownBox001Active, dropDown001EditMode)) dropDown001EditMode = !dropDown001EditMode;
GuiSetStyle(DROPDOWNBOX, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
if (GuiDropdownBox(new Rectangle(25, 25, 125, 30), "ONE;TWO;THREE", &dropdownBox000Active, dropDown000EditMode)) dropDown000EditMode = !dropDown000EditMode;
guiSetStyle(DROPDOWNBOX, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
if (guiDropdownBox(new Rectangle(25, 25, 125, 30), "ONE;TWO;THREE", dropdownBox000Active, dropDown000EditMode)) dropDown000EditMode = !dropDown000EditMode;
// Second GUI column
GuiListView(new Rectangle(165, 25, 140, 140), "Charmander;Bulbasaur;#18#Squirtel;Pikachu;Eevee;Pidgey", &listViewScrollIndex, &listViewActive);
GuiListViewEx(new Rectangle(165, 180, 140, 200), listViewExList, 8, &listViewExScrollIndex, &listViewExActive, &listViewExFocus);
listViewActive = guiListView(new Rectangle(165, 25, 140, 140), "Charmander;Bulbasaur;#18#Squirtel;Pikachu;Eevee;Pidgey", listViewScrollIndex, listViewActive);
//listViewExActive = guiListViewEx(new Rectangle(165, 180, 140, 200), listViewExList, 8, &listViewExFocus, &listViewExScrollIndex, listViewExActive);
//GuiToggle(new Rectangle(165, 400, 140, 25), "#1#ONE", &toggleGroupActive);
GuiToggleGroup(new Rectangle(165, 400, 140, 25), "#1#ONE\n#3#TWO\n#8#THREE\n#23#", &toggleGroupActive);
toggleGroupActive = guiToggleGroup(new Rectangle(165, 400, 140, 25), "#1#ONE\n#3#TWO\n#8#THREE\n#23#", toggleGroupActive);
// Third GUI column
GuiPanel(new Rectangle(320, 25, 225, 140), "Panel Info");
GuiColorPicker(new Rectangle(320, 185, 196, 192), NULL, &colorPickerValue);
guiPanel(new Rectangle(320, 25, 225, 140), "Panel Info");
colorPickerValue = guiColorPicker(new Rectangle(320, 185, 196, 192), null, colorPickerValue);
GuiSlider(new Rectangle(355, 400, 165, 20), "TEST", TextFormat("%2.2f", sliderValue), &sliderValue, -50, 100);
GuiSliderBar(new Rectangle(320, 430, 200, 20), NULL, TextFormat("%i", (int)sliderBarValue), &sliderBarValue, 0, 100);
GuiProgressBar(new Rectangle(320, 460, 200, 20), NULL, NULL, &progressValue, 0, 1);
sliderValue = guiSlider(new Rectangle(355, 400, 165, 20), "TEST", sliderValue.toString(), sliderValue, -50, 100);
sliderBarValue = guiSliderBar(new Rectangle(320, 430, 200, 20), null, sliderBarValue.toString(), sliderBarValue, 0, 100);
progressValue = guiProgressBar(new Rectangle(320, 460, 200, 20), null, null, progressValue, 0, 1);
// NOTE: View rectangle could be used to perform some scissor test
Rectangle view = { 0 };
GuiScrollPanel(new Rectangle(560, 25, 102, 354), NULL, new Rectangle(560, 25, 300, 1200), &viewScroll, &view);
let view = guiScrollPanel(new Rectangle(560, 25, 102, 354), null, new Rectangle(560, 25, 300, 1200), viewScroll);
Vector2 mouseCell = { 0 };
GuiGrid((Rectangle) { 560, 25 + 180 + 195, 100, 120 }, NULL, 20, 2, &mouseCell);
guiGrid(new Rectangle(560, 25 + 180 + 195, 100, 120), null, 20, 2);
GuiStatusBar(new Rectangle(0, (float)GetScreenHeight() - 20, (float)GetScreenWidth(), 20), "This is a status bar");
guiStatusBar(new Rectangle(0, getScreenHeight() - 20, getScreenWidth(), 20), "This is a status bar");
GuiColorBarAlpha(new Rectangle(320, 490, 200, 30), NULL, &alphaValue);
alphaValue = guiColorBarAlpha(new Rectangle(320, 490, 200, 30), null, alphaValue);
if (showMessageBox)
{
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(RAYWHITE, 0.8f));
int result = GuiMessageBox(new Rectangle((float)GetScreenWidth()/2 - 125, (float)GetScreenHeight()/2 - 50, 250, 100), GuiIconText(ICON_EXIT, "Close Window"), "Do you really want to exit?", "Yes;No");
drawRectangle(0, 0, getScreenWidth(), getScreenHeight(), fade(RAYWHITE, 0.8));
let result = guiMessageBox(new Rectangle(getScreenWidth()/2 - 125, getScreenHeight()/2 - 50, 250, 100), guiIconText(ICON_EXIT, "Close Window"), "Do you really want to exit?", "Yes;No");
if ((result == 0) || (result == 2)) showMessageBox = false;
else if (result == 1) exitWindow = true;
}
if (showTextInputBox)
{
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(RAYWHITE, 0.8f));
int result = GuiTextInputBox(new Rectangle((float)GetScreenWidth()/2 - 120, (float)GetScreenHeight()/2 - 60, 240, 140), "Save", GuiIconText(ICON_FILE_SAVE, "Save file as..."), "Ok;Cancel", textInput, 255, NULL);
// if (showTextInputBox)
// {
// drawRectangle(0, 0, getScreenWidth(), getScreenHeight(), fade(RAYWHITE, 0.8));
// let result = guiTextInputBox(new Rectangle(getScreenWidth()/2 - 120, getScreenHeight()/2 - 60, 240, 140), "Save", guiIconText(ICON_FILE_SAVE, "Save file as..."), "Ok;Cancel", textInput, 255, null);
if (result == 1)
{
// TODO: Validate textInput value and save
// if (result == 1)
// {
// // TODO: Validate textInput value and save
strcpy(textInputFileName, textInput);
}
// strcpy(textInputFileName, textInput);
// }
if ((result == 0) || (result == 1) || (result == 2))
{
showTextInputBox = false;
strcpy(textInput, "\0");
}
}
// if ((result == 0) || (result == 1) || (result == 2))
// {
// showTextInputBox = false;
// strcpy(textInput, "\0");
// }
// }
//----------------------------------------------------------------------------------
EndDrawing();
endDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
closeWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -403,8 +403,8 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator {
const sub = this.function("js_" + jsName, "JSValue", args, true);
return sub;
}
jsToC(type, name, src, classIds = {}, supressDeclaration = false) {
switch (type) {
jsToC(type, name, src, classIds = {}, supressDeclaration = false, typeAlias) {
switch (typeAlias ?? type) {
// Array Buffer
case "const void *":
case "void *":
@ -420,7 +420,7 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator {
break;
// String
case "const char *":
case "char *":
//case "char *":
if (!supressDeclaration)
this.statement(`${type} ${name} = (${type})JS_ToCString(ctx, ${src})`);
else
@ -463,7 +463,6 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator {
else
this.statement(`${name} = JS_ToBool(ctx, ${src})`);
break;
// Structs / Struct *
default:
const isConst = type.startsWith('const');
const isPointer = type.endsWith(' *');
@ -665,7 +664,10 @@ class RayLibHeader extends quickjs_1.QuickJsHeader {
if (api.params[i]?.binding?.ignore)
continue;
const para = api.params[i];
fun.jsToC(para.type, para.name, "argv[" + i + "]", this.structLookup);
if (para.binding?.customConverter)
para.binding.customConverter(fun);
else
fun.jsToC(para.type, para.name, "argv[" + i + "]", this.structLookup, false, para.binding?.typeAlias);
}
// call c function
if (options.customizeCall)
@ -674,6 +676,8 @@ class RayLibHeader extends quickjs_1.QuickJsHeader {
fun.call(api.name, api.params.map(x => x.name), api.returnType === "void" ? null : { type: api.returnType, name: "returnVal" });
// clean up parameters
for (const param of api.params) {
if (param.binding?.customCleanup)
param.binding.customCleanup(fun);
fun.jsCleanUpParameter(param.type, param.name);
}
// return result
@ -774,7 +778,7 @@ class TypeScriptDeclaration {
}
addFunction(name, api) {
const options = api.binding || {};
const para = (api.params || []).filter(x => !x.binding?.ignore).map(x => ({ name: x.name, type: this.toJsType(x.type) }));
const para = (api.params || []).filter(x => !x.binding?.ignore).map(x => ({ name: x.name, type: x.binding?.jsType ?? this.toJsType(x.type) }));
const returnType = options.jsReturns ?? this.toJsType(api.returnType);
this.functions.tsDeclareFunction(name, para, returnType, api.description);
}
@ -1253,6 +1257,7 @@ function main() {
getFunction(api.functions, "SaveFileData").binding = {};
ignore("ExportDataAsCode");
getFunction(api.functions, "LoadFileText").binding = { after: gen => gen.call("UnloadFileText", ["returnVal"]) };
getFunction(api.functions, "SaveFileText").params[1].binding = { typeAlias: "const char *" };
ignore("UnloadFileText");
const createFileList = (gen, loadName, unloadName, args) => {
gen.call(loadName, args, { type: "FilePathList", name: "files" });
@ -1377,14 +1382,29 @@ function main() {
ignore("QuaternionToAxisAngle");
core.exportGlobalConstant("DEG2RAD", "(PI/180.0)");
core.exportGlobalConstant("RAD2DEG", "(180.0/PI)");
ignore("GuiDropdownBox");
ignore("GuiSpinner");
ignore("GuiValueBox");
ignore("GuiListView");
const setOutParam = (fun, index) => {
const param = fun.params[index];
param.binding = {
jsType: `{ ${param.name}: number }`,
customConverter: gen => {
gen.declare(param.name + "_out", param.type.replace(" *", ""));
gen.declare(param.name, param.type, false, "&" + param.name + "_out");
},
customCleanup: gen => {
gen.call("JS_SetPropertyStr", ["ctx", "argv[" + index + "]", `"${param.name}"`, "JS_NewInt32(ctx," + param.name + "_out)"]);
}
};
};
setOutParam(getFunction(api.functions, "GuiDropdownBox"), 2);
setOutParam(getFunction(api.functions, "GuiSpinner"), 2);
setOutParam(getFunction(api.functions, "GuiValueBox"), 2);
setOutParam(getFunction(api.functions, "GuiListView"), 2);
ignore("GuiListViewEx");
ignore("GuiTextBox");
ignore("GuiTextInputBox");
ignore("GuiGetIcons");
//setOutParam(getFunction(api.functions, "GuiTextInputBox")!, 6)
ignore("GuiTabBar");
ignore("GuiGetIcons");
ignore("GuiLoadIcons");
// TODO: Parse and support light struct
ignore("CreateLight");

View File

@ -8907,16 +8907,55 @@ static JSValue js_guiComboBox(JSContext * ctx, JSValueConst this_val, int argc,
return ret;
}
static JSValue js_guiTextBox(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) {
static JSValue js_guiDropdownBox(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) {
Rectangle* bounds_ptr = (Rectangle*)JS_GetOpaque2(ctx, argv[0], js_Rectangle_class_id);
if(bounds_ptr == NULL) return JS_EXCEPTION;
Rectangle bounds = *bounds_ptr;
char * text = (char *)JS_ToCString(ctx, argv[1]);
int textSize;
JS_ToInt32(ctx, &textSize, argv[2]);
const char * text = (const char *)JS_ToCString(ctx, argv[1]);
int active_out;
int * active = &active_out;
bool editMode = JS_ToBool(ctx, argv[3]);
bool returnVal = GuiTextBox(bounds, text, textSize, editMode);
bool returnVal = GuiDropdownBox(bounds, text, active, editMode);
JS_FreeCString(ctx, text);
JS_SetPropertyStr(ctx, argv[2], "active", JS_NewInt32(ctx,active_out));
JSValue ret = JS_NewBool(ctx, returnVal);
return ret;
}
static JSValue js_guiSpinner(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) {
Rectangle* bounds_ptr = (Rectangle*)JS_GetOpaque2(ctx, argv[0], js_Rectangle_class_id);
if(bounds_ptr == NULL) return JS_EXCEPTION;
Rectangle bounds = *bounds_ptr;
const char * text = (const char *)JS_ToCString(ctx, argv[1]);
int value_out;
int * value = &value_out;
int minValue;
JS_ToInt32(ctx, &minValue, argv[3]);
int maxValue;
JS_ToInt32(ctx, &maxValue, argv[4]);
bool editMode = JS_ToBool(ctx, argv[5]);
bool returnVal = GuiSpinner(bounds, text, value, minValue, maxValue, editMode);
JS_FreeCString(ctx, text);
JS_SetPropertyStr(ctx, argv[2], "value", JS_NewInt32(ctx,value_out));
JSValue ret = JS_NewBool(ctx, returnVal);
return ret;
}
static JSValue js_guiValueBox(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) {
Rectangle* bounds_ptr = (Rectangle*)JS_GetOpaque2(ctx, argv[0], js_Rectangle_class_id);
if(bounds_ptr == NULL) return JS_EXCEPTION;
Rectangle bounds = *bounds_ptr;
const char * text = (const char *)JS_ToCString(ctx, argv[1]);
int value_out;
int * value = &value_out;
int minValue;
JS_ToInt32(ctx, &minValue, argv[3]);
int maxValue;
JS_ToInt32(ctx, &maxValue, argv[4]);
bool editMode = JS_ToBool(ctx, argv[5]);
bool returnVal = GuiValueBox(bounds, text, value, minValue, maxValue, editMode);
JS_FreeCString(ctx, text);
JS_SetPropertyStr(ctx, argv[2], "value", JS_NewInt32(ctx,value_out));
JSValue ret = JS_NewBool(ctx, returnVal);
return ret;
}
@ -9026,6 +9065,22 @@ static JSValue js_guiGrid(JSContext * ctx, JSValueConst this_val, int argc, JSVa
return ret;
}
static JSValue js_guiListView(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) {
Rectangle* bounds_ptr = (Rectangle*)JS_GetOpaque2(ctx, argv[0], js_Rectangle_class_id);
if(bounds_ptr == NULL) return JS_EXCEPTION;
Rectangle bounds = *bounds_ptr;
const char * text = (const char *)JS_ToCString(ctx, argv[1]);
int scrollIndex_out;
int * scrollIndex = &scrollIndex_out;
int active;
JS_ToInt32(ctx, &active, argv[3]);
int returnVal = GuiListView(bounds, text, scrollIndex, active);
JS_FreeCString(ctx, text);
JS_SetPropertyStr(ctx, argv[2], "scrollIndex", JS_NewInt32(ctx,scrollIndex_out));
JSValue ret = JS_NewInt32(ctx, returnVal);
return ret;
}
static JSValue js_guiMessageBox(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) {
Rectangle* bounds_ptr = (Rectangle*)JS_GetOpaque2(ctx, argv[0], js_Rectangle_class_id);
if(bounds_ptr == NULL) return JS_EXCEPTION;
@ -10153,13 +10208,16 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = {
JS_CFUNC_DEF("guiToggleGroup",3,js_guiToggleGroup),
JS_CFUNC_DEF("guiCheckBox",3,js_guiCheckBox),
JS_CFUNC_DEF("guiComboBox",3,js_guiComboBox),
JS_CFUNC_DEF("guiTextBox",4,js_guiTextBox),
JS_CFUNC_DEF("guiDropdownBox",4,js_guiDropdownBox),
JS_CFUNC_DEF("guiSpinner",6,js_guiSpinner),
JS_CFUNC_DEF("guiValueBox",6,js_guiValueBox),
JS_CFUNC_DEF("guiSlider",6,js_guiSlider),
JS_CFUNC_DEF("guiSliderBar",6,js_guiSliderBar),
JS_CFUNC_DEF("guiProgressBar",6,js_guiProgressBar),
JS_CFUNC_DEF("guiStatusBar",2,js_guiStatusBar),
JS_CFUNC_DEF("guiDummyRec",2,js_guiDummyRec),
JS_CFUNC_DEF("guiGrid",4,js_guiGrid),
JS_CFUNC_DEF("guiListView",4,js_guiListView),
JS_CFUNC_DEF("guiMessageBox",4,js_guiMessageBox),
JS_CFUNC_DEF("guiColorPicker",3,js_guiColorPicker),
JS_CFUNC_DEF("guiColorPanel",3,js_guiColorPanel),