From 05255b735ab93eb3ecb767b8ec8bb059530ee345 Mon Sep 17 00:00:00 2001 From: visionmercer <62051836+visionmercer@users.noreply.github.com> Date: Fri, 1 May 2026 11:29:53 +0200 Subject: [PATCH] Textinput added to ui lib --- include/ui.bm | 137 +++++++++++++++++++++++++++++++++++++++++++++++++- pixler.bas | 2 +- 2 files changed, 137 insertions(+), 2 deletions(-) diff --git a/include/ui.bm b/include/ui.bm index 02d755b..d6f67b5 100644 --- a/include/ui.bm +++ b/include/ui.bm @@ -1,4 +1,139 @@ +FUNCTION textinput$ (x AS INTEGER, y AS INTEGER, w AS INTEGER, h AS INTEGER, __text AS STRING) + DIM text AS STRING, keyin AS STRING + DIM cursor AS INTEGER, done AS INTEGER + DIM pasteData AS STRING + text = __text + ' Initial Hover Check + IF NOT (_MOUSEX > x AND _MOUSEY > y AND _MOUSEX < x + w AND _MOUSEY < y + h) THEN + drawtextinput x, y, w, h, __text, 0 + EXIT FUNCTION + END IF + drawtextinput x, y, w, h, __text, 1 + IF NOT mouseclicked THEN EXIT FUNCTION + text="" + cursor = LEN(text) + 1 + dim relativeX AS INTEGER + DO + keyin = INKEY$ + + ' Handle Extended Keys (Arrows, Home, End, Delete) + IF LEN(keyin) = 2 THEN + SELECT CASE ASC(RIGHT$(keyin, 1)) + CASE 75 ' Left Arrow + IF cursor > 1 THEN cursor = cursor - 1 + CASE 77 ' Right Arrow + IF cursor <= LEN(text) THEN cursor = cursor + 1 + CASE 71 ' Home Key + cursor = 1 + CASE 79 ' End Key + cursor = LEN(text) + 1 + CASE 83 ' Delete Key + IF cursor <= LEN(text) THEN + text = LEFT$(text, cursor - 1) + MID$(text, cursor + 1) + END IF + END SELECT + ELSEIF LEN(keyin) = 1 THEN + SELECT CASE ASC(keyin) + CASE 22 ' Ctrl + V (Paste) + ' Note: _CLIPBOARD$ is standard in modern BASIC like QB64 + pasteData = _CLIPBOARD$ + text = LEFT$(text, cursor - 1) + pasteData + MID$(text, cursor) + cursor = cursor + LEN(pasteData) + CASE 32 TO 126 ' Regular Typing + text = LEFT$(text, cursor - 1) + keyin + MID$(text, cursor) + cursor = cursor + 1 + CASE 8 ' Backspace + IF cursor > 1 THEN + text = LEFT$(text, cursor - 2) + MID$(text, cursor) + cursor = cursor - 1 + END IF + CASE 13 ' Enter + done = -1 + CASE 27 ' Escape (Cancel) + text = __text + done = -1 + END SELECT + END IF + + ' Send the cursor position to your drawing routine + drawtextinput x, y, w, h, text, cursor + + ' Check for clicks inside the box to reposition cursor + WHILE _MOUSEINPUT: WEND + IF _MOUSEBUTTON(1) THEN + IF (_MOUSEX >= x AND _MOUSEX <= x + w AND _MOUSEY >= y AND _MOUSEY <= y + h) THEN + relativeX = _MOUSEX - x + cursor = (relativeX \ 8) + 1 + + ' Constrain cursor to text boundaries + IF cursor < 1 THEN cursor = 1 + IF cursor > LEN(text) + 1 THEN cursor = LEN(text) + 1 + ELSE + done = -1 ' Clicked outside, exit focus + END IF + END IF + _LIMIT 60 + _DISPLAY + LOOP UNTIL done + textinput = text +END FUNCTION + +SUB drawtextinput (x AS INTEGER, y AS INTEGER, w AS INTEGER, h AS INTEGER, text AS STRING, state AS INTEGER) + DIM outtext AS STRING + DIM charWidth AS INTEGER: charWidth = 8 ' Standard font width + DIM cursorX AS INTEGER, textX AS INTEGER, textY AS INTEGER + + ' Background Drawing + IF state > 0 THEN ' If state is cursor pos, it's "active" + COLOR backgroundcolor1 + ELSE + COLOR backgroundcolor2 + END IF + LINE (x, y)-(x + w, y + h), , BF + + ' Border Drawing + IF state > 0 THEN + COLOR highlightcolor + ELSE + COLOR textcolor + END IF + LINE (x, y)-(x + w, y + h), , B + + ' Text Alignment Calculation + _PRINTMODE _KEEPBACKGROUND + ' We keep your original logic for scrolling/clipping text + outtext = RIGHT$(text, MIN(w / charWidth, LEN(text))) + + ' Calculate the starting X/Y for the text to center it + textX = 2 + x' + w / 2 - LEN(outtext) * charWidth / 2 + textY = 1 + y + h / 2 - 8 + + _PRINTSTRING (textX, textY), outtext + + ' --- Cursor Logic --- + IF state > 0 THEN + ' Calculate cursor position relative to the visible text + ' We use (TIMER * 2) to make it blink + IF INT(TIMER * 2) MOD 2 = 0 THEN + ' state is the cursor index (1-based) + ' We need to find where that character is relative to our clipped outtext + DIM relativeCursor AS INTEGER + relativeCursor = state - (LEN(text) - LEN(outtext)) + + ' Only draw if the cursor is actually within the visible box + IF relativeCursor >= 1 AND relativeCursor <= LEN(outtext) + 1 THEN + cursorX = textX + (relativeCursor - 1) * charWidth + ' Draw a vertical line for the cursor + LINE (cursorX, textY)-(cursorX, textY + 14), highlightcolor + END IF + END IF + END IF +END SUB + +function min(a,b) + if a<=b then min=a else min=b +end function function button (x as integer,y as integer,w as integer,h as integer,caption as string) if _mousex>x and _mousey>y and _mousex