-
-
Notifications
You must be signed in to change notification settings - Fork 255
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Textbox improvements! #57
Comments
I have a version without changing the function arguments, isntead i just have a new field in the Context That's in D, it's a WIP, i'll port it to C when the PR is ready: Peek.2021-12-23.21-14.mp4TODO:
BONUS:
int textbox_raw(Context *ctx, char *buf, int bufsz, Id id, Rect r, int opt)
{
Id lastFocus = ctx.focus;
int res = 0;
update_control(ctx, id, r, OPT_HOLDFOCUS);
if (ctx.focus != lastFocus && ctx.focus == id)
{
int len = cast(int) str_len(buf);
ctx.textbox_index = len;
ctx.textbox_select_min = 0;
ctx.textbox_select_max = 0;
}
if (ctx.focus == id)
{
scope(exit) (ctx.textbox_index)+=ctx.input_text_written;
/* handle text input */
int len = cast(int) str_len(buf);
int n = min(bufsz - len - 1, cast(int) str_len(ctx.input_text.ptr));
int i = ctx.textbox_index;
int needMove = len - i;
if (n > 0)
{
if (needMove > 0)
{
memmove(buf + i + n, buf + i, needMove);
}
memcpy(buf + i, ctx.input_text.ptr, n);
len += n;
buf[len] = '\0';
res |= RES_CHANGE;
}
/* handle backspace */
if ((ctx.key_pressed & KEY_BACKSPACE || ctx.key_repeated & KEY_BACKSPACE) && len > 0)
{
/* skip utf-8 continuation bytes */
while ((buf[--len] & 0xc0) == 0x80 && len > 0)
{
}
if (i > 0)
{
ctx.textbox_index --;
memmove(buf + (ctx.textbox_index), buf + (ctx.textbox_index) + 1, len - (ctx.textbox_index) + 1);
buf[len] = '\0';
res |= RES_CHANGE;
}
}
/* handle backspace */
if ((ctx.key_pressed & KEY_DELETE || ctx.key_repeated & KEY_DELETE) && len > 0)
{
if (len == 0 || i == (len+1)) goto skip;
memmove(buf + (ctx.textbox_index), buf + (ctx.textbox_index) + 1, len - (ctx.textbox_index) + 1);
buf[len] = '\0';
res |= RES_CHANGE;
}
skip:{}
if (ctx.mouse_pressed & MOUSE_LEFT && len > 0)
{
Font font = ctx.style.font;
int offsetX = ctx.mouse_pos.x - r.x;
int textw = ctx.text_width(font, buf, len);
int textwIndex = ctx.text_width(font, &buf[ctx.textbox_index], len);
int w = max(textw, textwIndex);
// click too far, set index to len
if (offsetX > textw)
{
LINFO("sup {} {} {}", offsetX, w, len);
ctx.textbox_index = len;
}
else
{
// TODO: doesn't work when text has scrolled..
// need to figure out a better way to handle this
// for now i guess that'll do...
// aaaaa[aaaaaaaaaaa]aaaaaa
int num = cast(int) (offsetX / cast(float) w * len);
// LINFO("les {} {} {}", offsetX, textw, num);
ctx.textbox_index = num;
}
}
/* handle return */
if (ctx.key_pressed & KEY_RETURN)
{
set_focus(ctx, 0);
res |= RES_SUBMIT;
}
else if (ctx.key_pressed & KEY_LEFT)
{
ctx.textbox_index--;
}
else if (ctx.key_pressed & KEY_RIGHT)
{
ctx.textbox_index ++;
}
if ((ctx.textbox_index) < 0) ctx.textbox_index = 0;
if (ctx.textbox_index >= len) ctx.textbox_index = len;
}
/* draw */
draw_control_frame(ctx, id, r, COLOR_BASE, 0);
if (ctx.focus == id)
{
Color color = ctx.style.colors[COLOR_TEXT];
Font font = ctx.style.font;
int textw = ctx.text_width(font, buf, ctx.textbox_index);
int texth = ctx.text_height(font);
int ofx = r.w - ctx.style.padding - textw - 1;
int textx = r.x + min(ofx, ctx.style.padding);
int texty = r.y + (r.h - texth) / 2;
push_clip_rect(ctx, r);
// text
draw_text(ctx, font, buf, -1, vec2(textx, texty), color);
// cursor
draw_rect(ctx, rect(textx + textw, texty, 1, texth), color);
// draw selection
if (ctx.textbox_select_min != ctx.textbox_select_max)
{
}
pop_clip_rect(ctx);
}
else
{
draw_control_text(ctx, buf, r, COLOR_TEXT, 0);
}
return res;
}
|
Hi @ryuukk did you ever finish this work to submit a PR? It would be very useful to have a standard solution for all microui users. |
@ryuukk , I am curious about this as well, since I could then port these changes to my port :P |
Hi, thanks for this awesome lib!
One thing that i felt was missing was proper textbox navigation, being able to correct a character without having to delete the entire thing
So i spent some time and managed to come up with something:
Peek.2021-12-23.05-28.mp4
Please let me know if you want to see more improvement to the code, so i can submit a PR!
Changes:
struct mu_Context { //. .. /* input state */ // ... char input_text[32]; + int input_text_written; };
/* reset input state */ ctx->key_pressed = 0; ctx->input_text[0] = '\0'; + ctx->input_text_written = 0;
void mu_input_text(mu_Context *ctx, const char *text) { int len = strlen(ctx->input_text); int size = strlen(text) + 1; expect(len + size <= (int) sizeof(ctx->input_text)); memcpy(ctx->input_text + len, text, size); + ctx.input_text_written += (size - 1); }
And here is how the new function looks like:
We basically introduce a new argument to the textbox_raw function
A pointer to an int so we can track the index, and user can specific where the index should start
The text was updated successfully, but these errors were encountered: