UNPKG

@wonderlandengine/editor-api

Version:

Wonderland Engine's Editor API for plugins - very experimental.

201 lines (200 loc) 6.03 kB
import { awaitJob } from './tools.js'; const ui = _wl_internalBinding('ui'); /** Image to be used in {@link ui}. */ export class UiImage { _id = -1; constructor(id) { this._id = id; } /** Manually mark this image as no longer needed */ free() { if (this._id >= 0) ui.freeImage(this._id); } } /** Simple text */ export const text = ui.text.bind(ui); /** Label for the next UI element */ export const label = ui.label.bind(ui); /** * Simple button * @param label Label for the button. * @returns `true` when pressed this frame. * * @example * In a draw function of a plugin, use as follows: * ```ts * if(ui.button('Click me!')) { * console.log('You clicked the button.'); * } * ``` */ export const button = ui.button.bind(ui); /** * Load a ui image. Any format supported by the editor is supported. * * @param filepath Path to the file. * @returns Promise with the loaded UiImage * * @example * In a draw function of a plugin, use as follows: * ```ts * this.thumbnail = null; * loadImage(fs.readFileSync("cache/plugins/my-plugin/downloads/thumbnail.png")) * .then((img) => this.thumbnail = img); * ``` * * @see image() */ export async function loadImage(data) { if (!(data instanceof ArrayBuffer)) { const converted = new Uint8Array(data.byteLength); for (let i = 0; i < data.byteLength; ++i) { converted[i] = data[i]; } data = converted.buffer; } /* Wrapper around a GL::Texture. People will be tempted calling * this in weird places, so better just throw it on the JobSystem * for the MainThread and spread it over time. */ const [job, imageId] = ui.loadImage(data); await awaitJob(job); return new UiImage(imageId); } export function image(image, width, height) { /* Since ImGui expects GL::Texture, we load the image for the user * from filepath. Avoids them pulling in pngjs and other mistakes */ return ui.image(image._id, width, height); } /** * Text input field. * * @param label Label to display next to the field. * @param value Current value to set the field to. * @returns The new string value when changed by the user this frame, otherwise `null`. * * @example * s = ui.inputText("change this:", s) || s; */ export const inputText = ui.inputText.bind(ui); /** * Text input field for passwords. * * Shows asterisks instead of the actual characters and disables copying. * * @param label Label to display next to the field. * @param value Current value to set the field to. * @returns The new string value when changed by the user this frame, otherwise `null`. * * @example * s = ui.inputTextPassword("change secret:", s) || s; */ export const inputTextPassword = ui.inputTextPassword.bind(ui); /** * Text input field for multiple lines. * * @param widgetId Unique id for the widget. * @param value Current value to set the field to. * @returns The new string value when changed by the user this frame, otherwise `null`. * * @example * s = ui.inputTextMultiline("change this:", s) || s; */ export const inputTextMultiline = ui.inputTextMultiline.bind(ui); /** * Checkbox. * * @param label Label to display next to the checkbox. * @param value Current value to set the checkbox to. * @returns The new boolean value when changed by the user this frame, otherwise `null`. * * @example * const n = ui.checkbox("change this:", myBool); * if(n !== null) myBool = n; */ export const checkbox = ui.checkbox.bind(ui); /** * Color picker for RGBA color. * * @param label Label to display next to the picker. * @param value Value to be in-place edited. * @returns `true` if changed by the user this frame, `false` otherwise. * * @example * const col = new Float32Array(4); * if(ui.colorEdit4("My color:", col)) { * console.log("Changed!"); * } */ export const colorEdit4 = ui.colorEdit4.bind(ui); /** * Dummy element (space). * * @param width Width of the dummy element * @param height Height of the dummy element */ export const dummy = ui.dummy.bind(ui); /** * Draw next widget on the same line. * * @param offset Offset on the x axis. */ export const sameLine = ui.sameLine.bind(ui); /** Separator line. */ export const separator = ui.separator.bind(ui); /** Begin a widget group. */ export const beginGroup = ui.beginGroup.bind(ui); /** End a widget group. */ export const endGroup = ui.endGroup.bind(ui); /** Spinner to indicate loading. */ export const spinner = ui.spinner.bind(ui); /** * Draggable float input * @param label Label for the input. * @param value Current value. * @returns The new value when changed by the user this frame, otherwise `null`. * * @example * let myFloat = 0; * const n = ui.inputFloat("change this:", myFloat); * if(n !== null) myFloat = n; */ export const inputFloat = ui.inputFloat.bind(ui); /** * Draggable float3 input * @param label Label for the input. * @param value Current value. * @returns `true` if changed by the user this frame, `false` otherwise. * * @example * const myFloat3 = new Float32Array(3); * if(ui.inputFloat3("change this:", myFloat3)) { * console.log("changed"); * } */ export const inputFloat3 = ui.inputFloat3.bind(ui); /** * Draggable int input * @param label Label for the input. * @param value Current value. * @returns The new value when changed by the user this frame, otherwise `null`. * * @example * let myInt = 0; * const n = ui.inputInt("change this:", myInt); * if(n !== null) myInt = n; */ export const inputInt = ui.inputInt.bind(ui); /** * Draggable int3 input * @param label Label for the input. * @param value Current value. * @returns `true` if changed by the user this frame, `false` otherwise. * * @example * const myInt3 = new Int32Array(3); * if(ui.inputInt3("change this:", myInt3)) { * console.log("changed"); * } */ export const inputInt3 = ui.inputInt3.bind(ui);