From a0f4b8309e7d07cbc9eef0ca1bc266e29c13e8ba Mon Sep 17 00:00:00 2001 From: Andrew Solomon Date: Fri, 22 Aug 2025 13:19:03 -0700 Subject: [PATCH 1/4] added support for multiple text boxes and backspace --- examples/text-input/App.jsx | 5 +- packages/muray/muray.cpp | 102 +++++++++++++++++++++++++++++++----- packages/murayact/index.js | 3 +- 3 files changed, 94 insertions(+), 16 deletions(-) diff --git a/examples/text-input/App.jsx b/examples/text-input/App.jsx index 19508d3..f72a45d 100644 --- a/examples/text-input/App.jsx +++ b/examples/text-input/App.jsx @@ -2,9 +2,12 @@ const React = require('react'); exports.App = () => { const [name, setName] = React.useState(""); + const [age, setAge] = React.useState(""); return
- setName(e.target.value)} placeholder='Input Text' /> + setName(e.target.value)} placeholder='Input Text' /> + + setAge(e.target.value)} />
; }; diff --git a/packages/muray/muray.cpp b/packages/muray/muray.cpp index dcddcb3..385162e 100644 --- a/packages/muray/muray.cpp +++ b/packages/muray/muray.cpp @@ -2,6 +2,8 @@ #ifdef __LINUX__ #include #endif +#include +#include #include #include extern "C" { @@ -9,9 +11,79 @@ extern "C" { } #define FONT_SIZE 20 +#define BUFFER_SIZE 2048 static mu_Context ctx = {0}; -static char input_buf[128]; + +struct InputField +{ + std::string id; + std::string buffer; + + std::vector cbuf; + InputField(const std::string &_id, const std::string initial = "", int bufsize = BUFFER_SIZE) : + id(_id), buffer(initial), cbuf(bufsize, 0) + { + strncpy(cbuf.data(), initial.c_str(), bufsize - 1); + } + + char *data() + { + return cbuf.data(); + } + + int size() + { + return cbuf.size(); + } + + void sync() + { + buffer = cbuf.data(); + } +}; + +struct InputList +{ + std::vector items; + + void add(const std::string &id, const std::string &initial = "", int bufsize = BUFFER_SIZE) + { + items.emplace_back(id, initial, bufsize); + } + + bool checkID(const std::string &id) + { + for (auto &field : items) + { + if(field.id == id) + return true; + } + return false; + } + + void render(mu_Context *ctx, char* id, const v8::FunctionCallbackInfo &args) + { + + if(!this->checkID(id)) this->add(id); + for (auto &field : items) + { + if(field.id == id) { + int val = mu_textbox(ctx, field.data(), field.size()); + if (val & MU_RES_CHANGE) + { + field.sync(); + mu_set_focus(ctx, ctx->last_id); + auto isolate = args.GetIsolate(); + args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, field.data()).ToLocalChecked()); + } + } + } + } +}; + +static InputList inputs; + static mu_Rect unclipped_rect = { 0, 0, 0x1000000, 0x1000000 }; void MuButton(const v8::FunctionCallbackInfo &args) { @@ -31,12 +103,8 @@ void MuLabel(const v8::FunctionCallbackInfo &args) { void MuInput(const v8::FunctionCallbackInfo &args) { auto isolate = args.GetIsolate(); auto context = isolate->GetCurrentContext(); - int val = mu_textbox(&ctx, input_buf, sizeof(input_buf)); - if (val & MU_RES_CHANGE) - { - mu_set_focus(&ctx, ctx.last_id); - args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, input_buf).ToLocalChecked()); - } + auto id = *v8::String::Utf8Value(isolate, args[0]->ToString(context).ToLocalChecked()); + inputs.render(&ctx, id, args); } void MuBeginWindow(const v8::FunctionCallbackInfo &args) { @@ -57,14 +125,20 @@ void MuUpdateInput(const v8::FunctionCallbackInfo &args) { if (IsMouseButtonReleased(button)) mu_input_mouseup (&ctx, x, y, 1 << button); } - char c; - char input[2]; - if ((c = GetCharPressed())) - { - input[0] = c; - input[1] = '\0'; - mu_input_text(&ctx, input); + int key; + while ((key = GetCharPressed())) { + mu_input_text(&ctx, (char[2]){(char)key, 0}); } + + if(IsKeyPressed(KEY_BACKSPACE)) mu_input_keydown(&ctx, MU_KEY_BACKSPACE); + if(IsKeyReleased(KEY_BACKSPACE)) mu_input_keyup(&ctx, MU_KEY_BACKSPACE); + + // I might be dumb, but i don't think MicroUI supports up down left right + // if(IsKeyPressed(KEY_LEFT)) mu_input_keydown(&ctx, MU_KEY_LEFT); + // if(IsKeyReleased(KEY_LEFT)) mu_input_keyup(&ctx, MU_KEY_LEFT); + + // if(IsKeyPressed(KEY_RIGHT)) mu_input_keydown(&ctx, MU_KEY_RIGHT); + // if(IsKeyReleased(KEY_RIGHT)) mu_input_keyup(&ctx, MU_KEY_RIGHT); } void MuBegin(const v8::FunctionCallbackInfo &args) { diff --git a/packages/murayact/index.js b/packages/murayact/index.js index 747bc3d..701703e 100644 --- a/packages/murayact/index.js +++ b/packages/murayact/index.js @@ -164,7 +164,8 @@ function renderElement(element) { { let placeholder = element.placeholder || ""; muray.mu_label(placeholder); - let value = muray.mu_input(); + if (element.id == undefined || element.id == "") throw "MISSING ID FOR TEXT INPUT"; + let value = muray.mu_input(element.id); if (value) { const evt = { target: { value } }; element.onChange(evt); From c100671a1ece31b8302366740f075d952ce35576 Mon Sep 17 00:00:00 2001 From: Andrew Solomon Date: Sun, 24 Aug 2025 15:50:22 -0700 Subject: [PATCH 2/4] Check for repeated backspace click Co-authored-by: Hugo --- packages/muray/muray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/muray/muray.cpp b/packages/muray/muray.cpp index 385162e..400f28a 100644 --- a/packages/muray/muray.cpp +++ b/packages/muray/muray.cpp @@ -130,7 +130,7 @@ void MuUpdateInput(const v8::FunctionCallbackInfo &args) { mu_input_text(&ctx, (char[2]){(char)key, 0}); } - if(IsKeyPressed(KEY_BACKSPACE)) mu_input_keydown(&ctx, MU_KEY_BACKSPACE); + if(IsKeyPressed(KEY_BACKSPACE) || IsKeyPressedRepeat(KEY_BACKSPACE)) mu_input_keydown(&ctx, MU_KEY_BACKSPACE); if(IsKeyReleased(KEY_BACKSPACE)) mu_input_keyup(&ctx, MU_KEY_BACKSPACE); // I might be dumb, but i don't think MicroUI supports up down left right From ad07429bfd718ba5f48d15998f9c222d0c407623 Mon Sep 17 00:00:00 2001 From: Andrew Solomon Date: Sun, 24 Aug 2025 15:50:55 -0700 Subject: [PATCH 3/4] fix pointer stuff Co-authored-by: Hugo --- packages/muray/muray.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/muray/muray.cpp b/packages/muray/muray.cpp index 400f28a..d776ad5 100644 --- a/packages/muray/muray.cpp +++ b/packages/muray/muray.cpp @@ -103,8 +103,8 @@ void MuLabel(const v8::FunctionCallbackInfo &args) { void MuInput(const v8::FunctionCallbackInfo &args) { auto isolate = args.GetIsolate(); auto context = isolate->GetCurrentContext(); - auto id = *v8::String::Utf8Value(isolate, args[0]->ToString(context).ToLocalChecked()); - inputs.render(&ctx, id, args); + auto id = v8::String::Utf8Value(isolate, args[0]->ToString(context).ToLocalChecked()); + inputs.render(&ctx, *id, args); } void MuBeginWindow(const v8::FunctionCallbackInfo &args) { From b778fbfe8555b4cd40fcab9963aecc89ea3ef136 Mon Sep 17 00:00:00 2001 From: Andrew Solomon Date: Wed, 27 Aug 2025 07:52:49 -0700 Subject: [PATCH 4/4] Added ability to customize raylib window size & layout is 1 column with -1 width --- examples/text-input/App.jsx | 2 +- examples/text-input/native.jsx | 1 + packages/muray/muray.cpp | 2 +- packages/murayact/index.js | 17 ++++++++++++++--- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/examples/text-input/App.jsx b/examples/text-input/App.jsx index f72a45d..ebc3451 100644 --- a/examples/text-input/App.jsx +++ b/examples/text-input/App.jsx @@ -6,7 +6,7 @@ exports.App = () => { return
- setName(e.target.value)} placeholder='Input Text' /> + setName(e.target.value)} placeholder="Please Input Text" /> setAge(e.target.value)} />
; diff --git a/examples/text-input/native.jsx b/examples/text-input/native.jsx index 2c8c3e5..e3555b8 100644 --- a/examples/text-input/native.jsx +++ b/examples/text-input/native.jsx @@ -2,4 +2,5 @@ const React = require('react'); const murayact = require('murayact'); const { App } = require('./App.js'); +murayact.initWindow(1440, 800); murayact.render(); \ No newline at end of file diff --git a/packages/muray/muray.cpp b/packages/muray/muray.cpp index d776ad5..e7945e5 100644 --- a/packages/muray/muray.cpp +++ b/packages/muray/muray.cpp @@ -109,7 +109,7 @@ void MuInput(const v8::FunctionCallbackInfo &args) { void MuBeginWindow(const v8::FunctionCallbackInfo &args) { mu_begin_window(&ctx, "Murayact", mu_rect(20, 20, 300, 300)); - mu_layout_row(&ctx, 2, (int[]) { 300, -1 }, 50); + mu_layout_row(&ctx, 1, (int[]) { -1 }, 40); } void MuEndWindow(const v8::FunctionCallbackInfo &args) { diff --git a/packages/murayact/index.js b/packages/murayact/index.js index 701703e..c77e672 100644 --- a/packages/murayact/index.js +++ b/packages/murayact/index.js @@ -117,6 +117,11 @@ const hostConfig = { } }, }; +const windowConfig = { + width: 800, + height: 600 +}; + const MurayRenderer = Reconciler(hostConfig); function renderTextElement(element) { @@ -162,8 +167,8 @@ function renderElement(element) { } break; case 'input': { - let placeholder = element.placeholder || ""; - muray.mu_label(placeholder); + // TODO: Add placeholder text into mu_textbox + // let placeholder = element.placeholder || ""; if (element.id == undefined || element.id == "") throw "MISSING ID FOR TEXT INPUT"; let value = muray.mu_input(element.id); if (value) { @@ -176,6 +181,12 @@ function renderElement(element) { } } +exports.initWindow = (width, height) => { + windowConfig.width = width; + windowConfig.height = height; + // TODO: Add more window configurations from native.js +} + exports.render = (element) => { const container = MurayRenderer.createContainer( { type: 'window' }, @@ -189,7 +200,7 @@ exports.render = (element) => { ); MurayRenderer.updateContainer(element, container); - muray.InitWindow(800, 600, "Hello from JavaScript"); + muray.InitWindow(windowConfig.width, windowConfig.height, "Hello from JavaScript"); while (!muray.WindowShouldClose()) { muray.mu_update_input(); muray.BeginDrawing();