Giter Site home page Giter Site logo

Textbox improvements! about microui HOT 3 OPEN

rxi avatar rxi commented on June 22, 2024 4
Textbox improvements!

from microui.

Comments (3)

ryuukk avatar ryuukk commented on June 22, 2024 4

I have a version without changing the function arguments, isntead i just have a new field in the Context
I also have some basic mouse functionality

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.mp4

TODO:

  • fix mouse selection when text has scrolled
  • implement proper selection support
  • add new style for selection colors
  • add new key shortcuts for
    • SHIFT + LEFT/RIGHT move selection
    • CTRL + LEFT/RIGHT for jumping to next block (word/delimiter)
    • CTRL + DEL/BACKSPACE for deleting a block

BONUS:

  • ideally this should support multi line text edits? or it should be a new control: textedit?
  • new copy/paste/cut command?
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;
}

from microui.

abnercoimbre avatar abnercoimbre commented on June 22, 2024

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.

from microui.

ericoporto avatar ericoporto commented on June 22, 2024

@ryuukk , I am curious about this as well, since I could then port these changes to my port :P

from microui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.