Author Topic: Experimental Input Box  (Read 4249 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Experimental Input Box
« on: February 03, 2021, 08:29:27 am »
So STx was talking about turning the OEInput into one that could create an ASCII input box (refer: https://www.qb64.org/forum/index.php?topic=1954.msg129200#msg129200 ), and I thought about doing that...

...Then I thought, why don't I just do something completely different and create a graphical input box that'll even work with SCREEN 0 screens??

And that's what we're seeing here:

Code: QB64: [Select]
  1.  
  2. 'Just some basic SCREEN 0 stuff to show that we're not messing with our background at all
  3. CLS , 1 'dark blue in screen 0
  4. PRINT "Foobie Foo FOO!"
  5. FOR I = 0 TO 15
  6.     COLOR I
  7.     PRINT "This is COLOR"; I
  8.  
  9.  
  10. result$ = InBox$("Input Box", "Generic User Input Goes Here") 'And here's a generic input box!
  11. PRINT "YOU ENTERED ==> "; result$
  12. 'And you can see the screen itself was maintained 100% as we had it before
  13.  
  14. InBox_Place -1, -1
  15. InBox_Size 300, 300
  16. InBox_Backgrounds _LOADIMAGE("cemetery.jpg", 32), 0
  17. InBox_Frame 3, Gold
  18. InBox_Title _LOADFONT("courbd.ttf", 32, "monospace"), SkyBlue, -1, Red, Blue
  19. InBox_Message _LOADFONT("courbd.ttf", 24, "monospace"), _LOADIMAGE("marble.jpg", 32), -1, &HFFFF0000&&, 0
  20. InBox_Input _LOADFONT("courbd.ttf", 18, "monospace"), LightGray, -1, Red, Blue
  21. result$ = InBox$("Math Box For Dummies", "Enter some maths!")
  22. PRINT "YOU ENTERED ==> "; result$
  23.  
  24.  
  25. SUB Inbox_reset
  26.     TYPE UDT
  27.         AS INTEGER X, Y, Wide, High, ErrorCode, Box_Justify_Hort, Box_Justify_Vert
  28.         AS INTEGER TitleFont, FrameSize, Title_Xoffset
  29.         AS INTEGER MessageFont, Message_Xoffset
  30.         AS INTEGER InputFont, Input_Xoffset, Inbox_Init
  31.         AS _INTEGER64 Screen_Background, Box_Background, Title_Background, Message_Background, Input_Background
  32.         AS _UNSIGNED LONG FrameColor, Title_Font_TextColor, Title_Font_TextBackColor
  33.         AS _UNSIGNED LONG Message_Font_TextColor, Message_Font_TextBackColor
  34.         AS _UNSIGNED LONG Input_Font_TextColor, Input_Font_TextBackColor
  35.         AS STRING Title, Message
  36.     END TYPE
  37.     SHARED InBox_Info AS UDT
  38.     'Default Inbox values
  39.     InBox_Info.Inbox_Init = -1
  40.     InBox_Place -1, -1
  41.     InBox_Size 400, 200
  42.     InBox_Backgrounds 0, &HFF000000&&
  43.     InBox_Frame 3, &HFFFFFFFF&&
  44.     InBox_Title 16, &HFF000000&&, -1, &HFFFFFFFF&&, &HFF000000&&
  45.     InBox_Message 16, &HFF000000&&, -1, &HFFFFFFFF&&, &HFF000000&&
  46.     InBox_Input 16, &HFFD3D3D3&&, -1, &HFF000000&&, 0
  47.  
  48. FUNCTION InBox$ (Title AS STRING, Prompt AS STRING)
  49.     SHARED InBox_Info AS UDT
  50.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  51.     'InBox_Info.ErrorCode
  52.     '1 = Attempting to make box wider than current screen allows.
  53.     '2 = Attempting to make box taller than current screen allows.
  54.     '3 = Attempting to place box off the left side of the allowable screen.
  55.     '4 = Attempting to place box above the top of the allowable screen.
  56.     '5 = Attempting to place box off the right side of the allowable screen.
  57.     '6 = Attempting to place box below the bottom of the allowable screen.
  58.     '7 = Invalid screen background image
  59.     '8 = Invalid box background image
  60.     '9 = Invalid box frame color
  61.     '10 = Invalid title font handle
  62.     '11 = Invalid title Xoffset (probably trying to print off the box)
  63.     '12 = Invalid message font handle
  64.  
  65.     STATIC AS LONG W, H, BPP, InBox_Software_Handle 'These are defined as STATIC as they're common variable
  66.     STATIC AS LONG D, S '                            names, and like this they won't interfer with any dummies
  67.     STATIC AS _INTEGER64 Xoffset '                   DIM SHARED variables.
  68.  
  69.     REDIM WordWrap(0) AS STRING '                    Redimmable array to hold properly formated word wrap text
  70.  
  71.  
  72.     D = _DEST: S = _SOURCE '                         Initial global state variables
  73.     A = _AUTODISPLAY
  74.  
  75.     W = _WIDTH: H = _HEIGHT: BPP = _PIXELSIZE
  76.     IF BPP = 0 THEN W = W * _FONTWIDTH: H = H * _FONTHEIGHT 'calculate text screen size, in pixels
  77.     InBox_Software_Handle = _NEWIMAGE(W, H, 32) '    Image size for our whole screen
  78.  
  79.  
  80.     IF InBox_Info.Wide > W THEN InBox_Info.ErrorCode = 1: GOTO clean_exit
  81.     IF InBox_Info.High > H THEN InBox_Info.ErrorCode = 2: GOTO clean_exit
  82.     IF InBox_Info.X < 0 THEN InBox_Info.ErrorCode = 3: GOTO clean_exit
  83.     IF InBox_Info.Y < 0 THEN InBox_Info.ErrorCode = 4: GOTO clean_exit
  84.     IF InBox_Info.X > W - InBox_Info.Wide THEN InBox_Info.ErrorCode = 5: GOTO clean_exit
  85.     IF InBox_Info.Y > H - InBox_Info.High THEN InBox_Info.ErrorCode = 6: GOTO clean_exit
  86.     IF InBox_Info.Screen_Background = -1 OR InBox_Info.Screen_Background > &HFFFFFFFF&& THEN InBox_Info.ErrorCode = 7: GOTO clean_exit
  87.     IF InBox_Info.Box_Background = -1 OR InBox_Info.Box_Background > &HFFFFFFFF&& THEN InBox_Info.ErrorCode = 8: GOTO clean_exit
  88.     IF InBox_Info.FrameColor < 0 OR InBox_Info.FrameColor > &HFFFFFFFF&& THEN InBox_Info.ErrorCode = 9: GOTO clean_exit
  89.     IF InBox_Info.TitleFont <= 0 THEN InBox_Info.ErrorCode = 10: GOTO clean_exit
  90.     IF InBox_Info.MessageFont <= 0 THEN InBox_Info.ErrorCode = 12: GOTO clean_exit
  91.  
  92.  
  93.     IF InBox_Info.Box_Justify_Hort THEN InBox_Info.X = (W - InBox_Info.Wide) \ 2
  94.     IF InBox_Info.Box_Justify_Vert THEN InBox_Info.Y = (H - InBox_Info.High) \ 2
  95.     InBox_Info.Title = Title: InBox_Info.Message = Prompt
  96.  
  97.     _DEST InBox_Software_Handle: _SOURCE InBox_Software_Handle
  98.  
  99.     'Stuff which we only draw once
  100.  
  101.     'This is the background for the whole screen, which we can use to cover up the original
  102.     IF InBox_Info.Screen_Background < -1 THEN
  103.         _PUTIMAGE (0, 0)-(W, H), InBox_Info.Screen_Background
  104.     ELSE
  105.         CLS , InBox_Info.Screen_Background
  106.     END IF
  107.  
  108.     'This is the background for the box itself.  Color or image, it doesn't matter.
  109.     IF InBox_Info.Box_Background < -1 THEN
  110.         _PUTIMAGE (InBox_Info.X, InBox_Info.Y)-STEP(InBox_Info.Wide, InBox_Info.High), InBox_Info.Box_Background
  111.     ELSE
  112.         LINE (InBox_Info.X, InBox_Info.Y)-STEP(InBox_Info.Wide, InBox_Info.High), InBox_Info.Box_Background, BF
  113.     END IF
  114.  
  115.     'This draws the frame around the whole box.
  116.     FOR I = 0 TO InBox_Info.FrameSize - 1
  117.         LINE (InBox_Info.X + I, InBox_Info.Y + I)-STEP(InBox_Info.Wide - 2 * I, InBox_Info.High - 2 * I), InBox_Info.FrameColor, B
  118.     NEXT
  119.  
  120.  
  121.     'and here we gather our information on what parts of the box is left for us to draw/write inside.
  122.     top = InBox_Info.Y + I: left = InBox_Info.X + I: right = left + InBox_Info.Wide - 2 * I: bottom = top + InBox_Info.High - 2 * I
  123.  
  124.  
  125.     '*****************************************  START TITLE *****************************************
  126.  
  127.     'This checks to make certain that our title is short enough to fit onto the screen
  128.     _FONT InBox_Info.TitleFont
  129.     T2WWA InBox_Info.Title, right - left, WordWrap()
  130.     totalprintarea = _FONTHEIGHT * (UBOUND(WordWrap) + 1)
  131.  
  132.     'I'm only allowing for the title to use up to a maximum of 1/3 of our total display area.
  133.     IF totalprintarea > (bottom - top) / 3 THEN 'more than that, and we toss an error.
  134.         InBox_Info.ErrorCode = 11: GOTO clean_exit
  135.     END IF
  136.  
  137.     'This is the background for the title area.  Color or image, it doesn't matter.
  138.     IF InBox_Info.Title_Background < -1 THEN
  139.         _PUTIMAGE (left, top)-(right, top + totalprintarea), InBox_Info.Title_Background
  140.     ELSE
  141.         LINE (left, top)-(right, top + totalprintarea), InBox_Info.Title_Background, BF
  142.     END IF
  143.  
  144.     'and here, we print the title, depending on its offset/justification
  145.     COLOR InBox_Info.Title_Font_TextColor, InBox_Info.Title_Font_TextBackColor
  146.     Xoffset = InBox_Info.Title_Xoffset
  147.     GOSUB Printout
  148.     '******************************************  END TITLE ******************************************
  149.     '************************************************************************************************
  150.     '****************************************  START MESSAGE ****************************************
  151.  
  152.     'This checks to make certain that our message is short enough to fit onto the screen
  153.     _FONT InBox_Info.MessageFont
  154.     T2WWA InBox_Info.Message, right - left, WordWrap()
  155.     totalprintarea = _FONTHEIGHT * (UBOUND(WordWrap) + 1)
  156.  
  157.     'I'm only allowing for the prompt message to use up to a maximum of 1/2 of our remaining display area.
  158.     IF totalprintarea > (bottom - top) / 2 THEN 'more than that, and we toss an error.
  159.         InBox_Info.ErrorCode = 11: GOTO clean_exit
  160.     END IF
  161.  
  162.     'This is the background for the message area.  Color or image, it doesn't matter.
  163.     IF InBox_Info.Message_Background < -1 THEN
  164.         _PUTIMAGE (left, top)-(right, bottom), InBox_Info.Message_Background
  165.     ELSE
  166.         LINE (left, top)-(right, bottom), InBox_Info.Message_Background, BF
  167.     END IF
  168.  
  169.     'and here, we print the message prompt, depending on its offset/justification
  170.     COLOR InBox_Info.Message_Font_TextColor, InBox_Info.Message_Font_TextBackColor
  171.     Xoffset = InBox_Info.Message_Xoffset: EE = -1
  172.     GOSUB Printout
  173.     '*****************************************  END MESSAGE *****************************************
  174.     '************************************************************************************************
  175.     '*****************************************  START INPUT *****************************************
  176.     top = top + 5: bottom = bottom - 5 '5 pixel area all around
  177.     left = left + 5: right = right - 5
  178.  
  179.     'This is the background for the input area.  Color or image, it doesn't matter.
  180.     fh = _FONTHEIGHT(InBox_Info.InputFont)
  181.     fw = _FONTWIDTH(InBox_Info.InputFont)
  182.     maxrows = (bottom - top) \ fh
  183.     maxcolumns = (right - left) \ fw
  184.     maxcharacters = maxrows * maxcolumns - 1 'for cursor
  185.  
  186.     left_right_offset = (right - left - maxcolumns * fw) \ 2
  187.     left = left + left_right_offset
  188.     right = right - left_right_offset
  189.     top = bottom - maxrows * fh
  190.  
  191.     IF InBox_Info.Input_Background < -1 THEN
  192.         _PUTIMAGE (left, top)-(right, bottom), InBox_Info.Input_Background
  193.     ELSE
  194.         LINE (left, top)-(right, bottom), InBox_Info.Input_Background, BF
  195.     END IF
  196.  
  197.  
  198.     Inbox_Software_Handle2 = _NEWIMAGE(right - left, bottom - top, 32)
  199.     Inbox_Software_Handle3 = _NEWIMAGE(right - left, bottom - top + fh * 2, 32)
  200.     _DEST Inbox_Software_Handle3: _SOURCE Inbox_Software_Handle3
  201.     COLOR InBox_Info.Input_Font_TextColor, InBox_Info.Input_Font_TextBackColor
  202.     _FONT InBox_Info.InputFont
  203.     '******************************************  END INPUT ******************************************
  204.     Inbox_Hardware_Handle = _COPYIMAGE(InBox_Software_Handle, 33)
  205.     DIM m AS _MEM: m = _MEMIMAGE(Inbox_Software_Handle3)
  206.     DO
  207.         _PUTIMAGE (0, 0), Inbox_Hardware_Handle
  208.         _PUTIMAGE (0, 0)-(right, bottom), Inbox_Software_Handle3, Inbox_Software_Handle2, (0, 0)-(right, bottom)
  209.         Inbox_Hardware_Handle2 = _COPYIMAGE(Inbox_Software_Handle2, 33)
  210.         _PUTIMAGE (left, top)-(right, bottom), Inbox_Hardware_Handle2
  211.  
  212.         IF _KEYDOWN(100307) OR _KEYDOWN(100308) THEN AltDown = -1 ELSE AltDown = 0
  213.         k = _KEYHIT
  214.         IF AltDown THEN
  215.             SELECT CASE k 'ignore all keypresses except ALT-number presses
  216.                 CASE 48 TO 57: AltWasDown = -1: alt$ = alt$ + CHR$(k)
  217.             END SELECT
  218.         ELSE
  219.             SELECT CASE k 'without alt, add any keypresses to our input
  220.                 CASE 8
  221.                     oldin$ = in$
  222.                     IF CP > 0 THEN OldCP = CP: CP = CP - 1
  223.                     in$ = LEFT$(in$, CP) + MID$(in$, CP + 2) 'backspace to erase input
  224.                 CASE 9
  225.                     oldin$ = in$
  226.                     in$ = LEFT$(in$, CP) + SPACE$(4) + MID$(in$, CP + 1) 'four spaces for any TAB entered
  227.                     OldCP = CP
  228.                     CP = CP + 4
  229.                 CASE 32 TO 128
  230.                     IF _KEYDOWN(100305) OR _KEYDOWN(100306) THEN
  231.                         IF k = 118 OR k = 86 THEN
  232.                             oldin$ = in$
  233.                             in$ = LEFT$(in$, CP) + _CLIPBOARD$ + MID$(in$, CP + 1) 'ctrl-v paste
  234.                             'CTRL-V leaves cursor in position before the paste, without moving it after.
  235.                             'Feel free to modify that behavior here, if you want it to move to after the paste.
  236.                         END IF
  237.                         IF k = 122 OR k = 90 THEN SWAP in$, oldin$: SWAP OldCP, CP 'ctrl-z undo
  238.                     ELSE
  239.                         oldin$ = in$
  240.                         in$ = LEFT$(in$, CP) + CHR$(k) + MID$(in$, CP + 1) 'add input to our string
  241.                         OldCP = CP
  242.                         CP = CP + 1
  243.                     END IF
  244.                 CASE 18176 'Home
  245.                     CP = 0
  246.                 CASE 20224 'End
  247.                     CP = LEN(in$)
  248.                 CASE 21248 'Delete
  249.                     oldin$ = in$
  250.                     in$ = LEFT$(in$, CP) + MID$(in$, CP + 2)
  251.                 CASE 19200 'Left
  252.                     CP = CP - 1
  253.                     IF CP < 0 THEN CP = 0
  254.                 CASE 19712 'Right
  255.                     CP = CP + 1
  256.                     IF CP > LEN(in$) THEN CP = LEN(in$)
  257.             END SELECT
  258.         END IF
  259.         alt$ = RIGHT$(alt$, 3)
  260.         IF AltWasDown = -1 AND AltDown = 0 THEN
  261.             v = VAL(alt$)
  262.             IF v >= 0 AND v <= 255 THEN in$ = in$ + CHR$(v)
  263.             alt$ = "": AltWasDown = 0
  264.         END IF
  265.         blink = (blink + 1) MOD 30
  266.  
  267.         in$ = LEFT$(in$, maxcharacters) ' a limit, for now, of no more characters than the screen can hold
  268.         IF CP >= maxcharacters THEN CP = maxcharacters 'part of the temporary limit
  269.         _DEST Inbox_Software_Handle2: _SOURCE Inbox_Software_Handle2
  270.         CLS , 0
  271.         _DEST Inbox_Software_Handle3: _SOURCE Inbox_Software_Handle3
  272.         CLS , 0
  273.         LOCATE 1, 1
  274.  
  275.         PRINT LEFT$(in$, CP);
  276.         IF blink \ 15 THEN PRINT " "; ELSE PRINT "_";
  277.         PRINT MID$(in$, CP + 1);
  278.  
  279.         _DISPLAY
  280.         _LIMIT 60
  281.     LOOP UNTIL k = 13
  282.  
  283.     clean_exit:
  284.     _DEST D: _SOURCE S
  285.     _FREEIMAGE InBox_Software_Handle
  286.     _FREEIMAGE Inbox_Software_Handle2
  287.     _FREEIMAGE Inbox_Software_Handle3
  288.  
  289.     InBox$ = in$
  290.     EXIT SUB
  291.  
  292.     Printout:
  293.  
  294.     'This is where we print actual lines to the inbox display
  295.     FOR I = 0 TO UBOUND(WordWrap)
  296.         IF Xoffset >= 0 THEN
  297.             _PRINTSTRING (left, top + _FONTHEIGHT * I), WordWrap(I)
  298.         ELSE
  299.             l = (right - left - _PRINTWIDTH(WordWrap(I))) / 2
  300.             _PRINTSTRING (left + l, top + _FONTHEIGHT * I), WordWrap(I)
  301.         END IF
  302.     NEXT
  303.  
  304.     'update the available screen positions
  305.     top = top + _FONTHEIGHT * (UBOUND(WordWrap) + 1)
  306.  
  307.     IF EE THEN EE = 0: RETURN 'Exit Early code to avoid drawing the frame
  308.  
  309.     'draw the frame again, below the title
  310.     LINE (left, top)-(right, top + InBox_Info.FrameSize), InBox_Info.FrameColor, BF
  311.  
  312.     'update the available screen positons once again
  313.     top = top + InBox_Info.FrameSize
  314.     RETURN
  315.  
  316.  
  317. SUB InBox_Place (x AS INTEGER, y AS INTEGER)
  318.     SHARED InBox_Info AS UDT
  319.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  320.     IF x < 0 THEN
  321.         InBox_Info.X = 0
  322.         InBox_Info.Box_Justify_Hort = -1
  323.     ELSE
  324.         InBox_Info.X = x
  325.         InBox.Box_Justify_Hort = 0
  326.     END IF
  327.     IF y < 0 THEN
  328.         InBox_Info.Y = 0
  329.         InBox_Info.Box_Justify_Vert = -1
  330.     ELSE
  331.         InBox_Info.Y = y
  332.         InBox_Info.Box_Justify_Vert = 0
  333.     END IF
  334.  
  335. SUB InBox_Size (wide AS INTEGER, high AS INTEGER)
  336.     SHARED InBox_Info AS UDT
  337.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  338.     InBox_Info.Wide = wide
  339.     InBox_Info.High = high
  340.  
  341. SUB InBox_Backgrounds (Screen_background AS _INTEGER64, Box_background AS _INTEGER64)
  342.     SHARED InBox_Info AS UDT
  343.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  344.     InBox_Info.Screen_Background = Screen_background
  345.     InBox_Info.Box_Background = Box_background
  346.  
  347. SUB InBox_Frame (size AS INTEGER, kolor AS _INTEGER64)
  348.     SHARED InBox_Info AS UDT
  349.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  350.     InBox_Info.FrameColor = kolor
  351.     InBox_Info.FrameSize = size
  352.  
  353. SUB InBox_Title (font%, background&&, xOffset%, fc~&, fbg~&)
  354.     SHARED InBox_Info AS UDT
  355.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  356.     InBox_Info.TitleFont = font%
  357.     InBox_Info.Title_Background = background&&
  358.     InBox_Info.Title_Xoffset = xOffset%
  359.     InBox_Info.Title_Font_TextColor = fc~&
  360.     InBox_Info.Title_Font_TextBackColor = fbg~&
  361.  
  362. SUB InBox_Message (font%, background&&, xOffset%, fc~&, fbg~&)
  363.     SHARED InBox_Info AS UDT
  364.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  365.     InBox_Info.MessageFont = font%
  366.     InBox_Info.Message_Background = background&&
  367.     InBox_Info.Message_Xoffset = xOffset%
  368.     InBox_Info.Message_Font_TextColor = fc~&
  369.     InBox_Info.Message_Font_TextBackColor = fbg~&
  370.  
  371. SUB InBox_Input (font%, background&&, xOffset%, fc~&, fbg~&)
  372.     SHARED InBox_Info AS UDT
  373.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  374.     InBox_Info.InputFont = font%
  375.     InBox_Info.Input_Background = background&&
  376.     InBox_Info.Input_Xoffset = xOffset%
  377.     InBox_Info.Input_Font_TextColor = fc~&
  378.     InBox_Info.Input_Font_TextBackColor = fbg~&
  379.  
  380.  
  381. SUB T2WWA (temp$, wide%, result() AS STRING) 'Text To Word Wrap Array
  382.     DIM BreakPoint AS STRING
  383.     BreakPoint = ",./- ;:!" 'I consider all these to be valid breakpoints.  If you want something else, change them.
  384.  
  385.     text$ = _TRIM$(temp$)
  386.     DO
  387.         'first find the natural length of the line
  388.         FOR i = 1 TO LEN(text$)
  389.             p = _PRINTWIDTH(LEFT$(text$, i))
  390.             IF p > wide% THEN EXIT FOR
  391.         NEXT
  392.         IF p < wide% THEN result(count) = RTRIM$(text$): GOTO clean_exit
  393.         lineend = i - 1
  394.         t$ = RTRIM$(LEFT$(text$, lineend)) 'at most, our line can't be any longer than what fits the screen.
  395.         FOR i = lineend TO 1 STEP -1
  396.             IF INSTR(BreakPoint, MID$(text$, i, 1)) THEN lineend = i: EXIT FOR
  397.         NEXT
  398.         result(count) = RTRIM$(LEFT$(text$, lineend))
  399.         count = count + 1
  400.         IF count > UBOUND(result) THEN REDIM _PRESERVE result(count + 100) AS STRING
  401.         text$ = LTRIM$(MID$(text$, lineend + 1))
  402.     LOOP UNTIL text$ = ""
  403.     clean_exit:
  404.     REDIM _PRESERVE result(count) AS STRING
  405.  

Now, there's a LOT of things that I wouldn't recommend doing, like I've done here -- such as using multiple _LOADIMAGE and _LOADFONT commands, with no way to free those resources...   but for a demo, this should work well enough.

I also wouldn't recommend going with the tacky sizes and color schemes that I'm using for the custom window, but they're there to show how many different aspects of the window are customizable.  Backgrounds can be colors, or they can be images -- it doesn't matter.  Fonts really don't matter, except they need to be monospaced.  (And that'll be correct when/if I fix the input to become scrollable.)

At the moment, we can input multi-line text, but only up to the amount of text that fits our input area.  I'm thinking of doing a little tweaking of this later (like next week probably, if I don't move on to something else and forget about this by then), so that it'll work with unlimited length text.  The text input will actually work with it right now, but I've got an artificial limit in place, just cause my CP (Cursor Position) gets all jumbled if I don't, and I haven't sorted it out yet...  All it needs is a quick sort, and then unlimited input text length shouldn't be an issue any more.

Test it out.  Try and break it.  And enjoy it, if it can be of any use to you.

Suggestions for alterations, enhancements, and bug reports are more than welcome.
cemetery.jpg
* cemetery.jpg (Filesize: 172.44 KB, Dimensions: 1280x960, Views: 246)
marble.jpg
* marble.jpg (Filesize: 4.86 KB, Dimensions: 204x204, Views: 243)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Experimental Input Box
« Reply #1 on: February 03, 2021, 09:14:36 am »
That looks great. Cant wait to get back home today so i can try it out! I was kind of dabbling with making a simular thing, but yours looks all done and polished.

Edit: hmm, i've never really paid attention to the $color metacommand before. I can see how it can come in handy.

- Dav
« Last Edit: February 03, 2021, 09:29:21 am by Dav »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Experimental Input Box
« Reply #2 on: February 03, 2021, 09:30:05 am »
That looks great. Cant wait to get back home today so i can try it out! I was kind of dabbling with making a simular thing, but yours looks all done and polished.

Edit: hmm, i've never really paid attention to the $color metacommand before. I can see now where it can come in handy.

- Dav

It just lets you plug in color names for preset color values.   COLOR Gold, Purple, for instance.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Experimental Input Box
« Reply #3 on: February 03, 2021, 10:18:37 am »
I ran back home to get something, and tried out the code. Works well!  Needs v1.5 to use the new DIM method, for those interested. 

Saving it for my toolbox.  I'll give it a good work out later today. So far it seems to work perfectly.

Thanks for sharing.


Edit:  I'm sorry, I meant the new way of combing variables like DIM/TYPE can do now:  AS INTEGER X, Y, Wide, High, etc...

- Dav
« Last Edit: February 03, 2021, 10:39:20 am by Dav »

Marked as best answer by SMcNeill on February 03, 2021, 09:43:53 am

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Experimental Input Box
« Reply #4 on: February 03, 2021, 02:15:20 pm »
Updated:  We now work with scrollable input boxes, with a maximum of 65535 characters (or less, as font size and input width/height limitations allow).  There's a little counter at the bottom of the input area now where it tells you how many characters you've used, and what the limit is that you can type into the box with the current settings.

Code: QB64: [Select]
  1.  
  2. 'Just some basic SCREEN 0 stuff to show that we're not messing with our background at all
  3. CLS , 1 'dark blue in screen 0
  4. PRINT "Foobie Foo FOO!"
  5. FOR I = 0 TO 15
  6.     COLOR I
  7.     PRINT "This is COLOR"; I
  8.  
  9. InBox_Size 150, 150
  10. result$ = InBox$("Input Box", "Generic User Input Goes Here") 'And here's a generic input box!
  11. PRINT "YOU ENTERED ==> "; result$
  12. 'And you can see the screen itself was maintained 100% as we had it before, except for the result$
  13. 'which we printed after closing the InBox
  14.  
  15. InBox_Place -1, -1
  16. InBox_Size 300, 300
  17. InBox_Backgrounds _LOADIMAGE("cemetery.jpg", 32), 0
  18. InBox_Frame 3, Gold
  19. InBox_Title _LOADFONT("courbd.ttf", 32, "monospace"), SkyBlue, -1, Red, Blue
  20. InBox_Message _LOADFONT("courbd.ttf", 24, "monospace"), _LOADIMAGE("marble.jpg", 32), -1, &HFFFF0000&&, 0
  21. InBox_Input _LOADFONT("courbd.ttf", 18, "monospace"), LightGray, -1, Red, Blue
  22. result$ = InBox$("Math Box For Dummies", "Enter some maths!")
  23. PRINT "YOU ENTERED ==> "; result$
  24.  
  25.  
  26. SUB Inbox_reset
  27.     TYPE UDT
  28.         AS INTEGER X, Y, Wide, High, ErrorCode, Box_Justify_Hort, Box_Justify_Vert
  29.         AS INTEGER TitleFont, FrameSize, Title_Xoffset
  30.         AS INTEGER MessageFont, Message_Xoffset
  31.         AS INTEGER InputFont, Input_Xoffset, Inbox_Init
  32.         AS _INTEGER64 Screen_Background, Box_Background, Title_Background, Message_Background, Input_Background
  33.         AS _UNSIGNED LONG FrameColor, Title_Font_TextColor, Title_Font_TextBackColor
  34.         AS _UNSIGNED LONG Message_Font_TextColor, Message_Font_TextBackColor
  35.         AS _UNSIGNED LONG Input_Font_TextColor, Input_Font_TextBackColor
  36.         AS STRING Title, Message
  37.     END TYPE
  38.     SHARED InBox_Info AS UDT
  39.     'Default Inbox values
  40.     InBox_Info.Inbox_Init = -1
  41.     InBox_Place -1, -1
  42.     InBox_Size 400, 200
  43.     InBox_Backgrounds 0, &HFF000000&&
  44.     InBox_Frame 3, &HFFFFFFFF&&
  45.     InBox_Title 16, &HFF000000&&, -1, &HFFFFFFFF&&, &HFF000000&&
  46.     InBox_Message 16, &HFF000000&&, -1, &HFFFFFFFF&&, &HFF000000&&
  47.     InBox_Input 16, &HFFD3D3D3&&, -1, &HFF000000&&, 0
  48.  
  49. FUNCTION InBox$ (Title AS STRING, Prompt AS STRING)
  50.     SHARED InBox_Info AS UDT
  51.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  52.     'InBox_Info.ErrorCode
  53.     '1 = Attempting to make box wider than current screen allows.
  54.     '2 = Attempting to make box taller than current screen allows.
  55.     '3 = Attempting to place box off the left side of the allowable screen.
  56.     '4 = Attempting to place box above the top of the allowable screen.
  57.     '5 = Attempting to place box off the right side of the allowable screen.
  58.     '6 = Attempting to place box below the bottom of the allowable screen.
  59.     '7 = Invalid screen background image
  60.     '8 = Invalid box background image
  61.     '9 = Invalid box frame color
  62.     '10 = Invalid title font handle
  63.     '11 = Invalid title Xoffset (probably trying to print off the box)
  64.     '12 = Invalid message font handle
  65.  
  66.     STATIC AS LONG W, H, BPP, InBox_Software_Handle 'These are defined as STATIC as they're common variable
  67.     STATIC AS LONG D, S '                            names, and like this they won't interfer with any dummies
  68.     STATIC AS _INTEGER64 Xoffset '                   DIM SHARED variables.
  69.  
  70.     REDIM WordWrap(0) AS STRING '                    Redimmable array to hold properly formated word wrap text
  71.  
  72.  
  73.     D = _DEST: S = _SOURCE '                         Initial global state variables
  74.     A = _AUTODISPLAY
  75.  
  76.     W = _WIDTH: H = _HEIGHT: BPP = _PIXELSIZE
  77.     IF BPP = 0 THEN W = W * _FONTWIDTH: H = H * _FONTHEIGHT 'calculate text screen size, in pixels
  78.     InBox_Software_Handle = _NEWIMAGE(W, H, 32) '    Image size for our whole screen
  79.  
  80.  
  81.     IF InBox_Info.Wide > W THEN InBox_Info.ErrorCode = 1: GOTO clean_exit
  82.     IF InBox_Info.High > H THEN InBox_Info.ErrorCode = 2: GOTO clean_exit
  83.     IF InBox_Info.X < 0 THEN InBox_Info.ErrorCode = 3: GOTO clean_exit
  84.     IF InBox_Info.Y < 0 THEN InBox_Info.ErrorCode = 4: GOTO clean_exit
  85.     IF InBox_Info.X > W - InBox_Info.Wide THEN InBox_Info.ErrorCode = 5: GOTO clean_exit
  86.     IF InBox_Info.Y > H - InBox_Info.High THEN InBox_Info.ErrorCode = 6: GOTO clean_exit
  87.     IF InBox_Info.Screen_Background = -1 OR InBox_Info.Screen_Background > &HFFFFFFFF&& THEN InBox_Info.ErrorCode = 7: GOTO clean_exit
  88.     IF InBox_Info.Box_Background = -1 OR InBox_Info.Box_Background > &HFFFFFFFF&& THEN InBox_Info.ErrorCode = 8: GOTO clean_exit
  89.     IF InBox_Info.FrameColor < 0 OR InBox_Info.FrameColor > &HFFFFFFFF&& THEN InBox_Info.ErrorCode = 9: GOTO clean_exit
  90.     IF InBox_Info.TitleFont <= 0 THEN InBox_Info.ErrorCode = 10: GOTO clean_exit
  91.     IF InBox_Info.MessageFont <= 0 THEN InBox_Info.ErrorCode = 12: GOTO clean_exit
  92.  
  93.  
  94.     IF InBox_Info.Box_Justify_Hort THEN InBox_Info.X = (W - InBox_Info.Wide) \ 2
  95.     IF InBox_Info.Box_Justify_Vert THEN InBox_Info.Y = (H - InBox_Info.High) \ 2
  96.     InBox_Info.Title = Title: InBox_Info.Message = Prompt
  97.  
  98.     _DEST InBox_Software_Handle: _SOURCE InBox_Software_Handle
  99.  
  100.     'Stuff which we only draw once
  101.  
  102.     'This is the background for the whole screen, which we can use to cover up the original
  103.     IF InBox_Info.Screen_Background < -1 THEN
  104.         _PUTIMAGE (0, 0)-(W, H), InBox_Info.Screen_Background
  105.     ELSE
  106.         CLS , InBox_Info.Screen_Background
  107.     END IF
  108.  
  109.     'This is the background for the box itself.  Color or image, it doesn't matter.
  110.     IF InBox_Info.Box_Background < -1 THEN
  111.         _PUTIMAGE (InBox_Info.X, InBox_Info.Y)-STEP(InBox_Info.Wide, InBox_Info.High), InBox_Info.Box_Background
  112.     ELSE
  113.         LINE (InBox_Info.X, InBox_Info.Y)-STEP(InBox_Info.Wide, InBox_Info.High), InBox_Info.Box_Background, BF
  114.     END IF
  115.  
  116.     'This draws the frame around the whole box.
  117.     FOR I = 0 TO InBox_Info.FrameSize - 1
  118.         LINE (InBox_Info.X + I, InBox_Info.Y + I)-STEP(InBox_Info.Wide - 2 * I, InBox_Info.High - 2 * I), InBox_Info.FrameColor, B
  119.     NEXT
  120.  
  121.  
  122.     'and here we gather our information on what parts of the box is left for us to draw/write inside.
  123.     top = InBox_Info.Y + I: left = InBox_Info.X + I: right = left + InBox_Info.Wide - 2 * I: bottom = top + InBox_Info.High - 2 * I
  124.  
  125.  
  126.     '*****************************************  START TITLE *****************************************
  127.  
  128.     'This checks to make certain that our title is short enough to fit onto the screen
  129.     _FONT InBox_Info.TitleFont
  130.     T2WWA InBox_Info.Title, right - left, WordWrap()
  131.     totalprintarea = _FONTHEIGHT * (UBOUND(WordWrap) + 1)
  132.  
  133.     'I'm only allowing for the title to use up to a maximum of 1/3 of our total display area.
  134.     IF totalprintarea > (bottom - top) / 3 THEN 'more than that, and we toss an error.
  135.         InBox_Info.ErrorCode = 11: GOTO clean_exit
  136.     END IF
  137.  
  138.     'This is the background for the title area.  Color or image, it doesn't matter.
  139.     IF InBox_Info.Title_Background < -1 THEN
  140.         _PUTIMAGE (left, top)-(right, top + totalprintarea), InBox_Info.Title_Background
  141.     ELSE
  142.         LINE (left, top)-(right, top + totalprintarea), InBox_Info.Title_Background, BF
  143.     END IF
  144.  
  145.     'and here, we print the title, depending on its offset/justification
  146.     COLOR InBox_Info.Title_Font_TextColor, InBox_Info.Title_Font_TextBackColor
  147.     Xoffset = InBox_Info.Title_Xoffset
  148.     GOSUB Printout
  149.     '******************************************  END TITLE ******************************************
  150.     '************************************************************************************************
  151.     '****************************************  START MESSAGE ****************************************
  152.  
  153.     'This checks to make certain that our message is short enough to fit onto the screen
  154.     _FONT InBox_Info.MessageFont
  155.     T2WWA InBox_Info.Message, right - left, WordWrap()
  156.     totalprintarea = _FONTHEIGHT * (UBOUND(WordWrap) + 1)
  157.  
  158.     'I'm only allowing for the prompt message to use up to a maximum of 1/2 of our remaining display area.
  159.     IF totalprintarea > (bottom - top) / 2 THEN 'more than that, and we toss an error.
  160.         InBox_Info.ErrorCode = 11: GOTO clean_exit
  161.     END IF
  162.  
  163.     'This is the background for the message area.  Color or image, it doesn't matter.
  164.     IF InBox_Info.Message_Background < -1 THEN
  165.         _PUTIMAGE (left, top)-(right, bottom), InBox_Info.Message_Background
  166.     ELSE
  167.         LINE (left, top)-(right, bottom), InBox_Info.Message_Background, BF
  168.     END IF
  169.  
  170.     'and here, we print the message prompt, depending on its offset/justification
  171.     COLOR InBox_Info.Message_Font_TextColor, InBox_Info.Message_Font_TextBackColor
  172.     Xoffset = InBox_Info.Message_Xoffset: EE = -1
  173.     GOSUB Printout
  174.     '*****************************************  END MESSAGE *****************************************
  175.     '************************************************************************************************
  176.     '*****************************************  START INPUT *****************************************
  177.     left = left + 5: right = right - 5 '5 pixel area all around
  178.  
  179.     'This is the background for the input area.  Color or image, it doesn't matter.
  180.     fh = _FONTHEIGHT(InBox_Info.InputFont)
  181.     fw = _FONTWIDTH(InBox_Info.InputFont)
  182.     maxrows = (bottom - top - 20) \ fh
  183.     maxcolumns = (right - left) \ fw
  184.     maxcharacters = maxrows * maxcolumns - 1 'for cursor
  185.     maxcharacters = 65534
  186.     absolutemax = (65535 \ fh) * maxcolumns
  187.     IF absolutemax < maxcharacters THEN maxcharacters = absolutemax
  188.  
  189.     left_right_offset = (right - left - maxcolumns * fw) \ 2
  190.     left = left + left_right_offset
  191.     right = right - left_right_offset
  192.     top = bottom - (maxrows + 1) * fh - 2
  193.  
  194.     IF InBox_Info.Input_Background < -1 THEN
  195.         _PUTIMAGE (left, top)-(right, bottom - 20), InBox_Info.Input_Background
  196.     ELSE
  197.         LINE (left, top)-(right, bottom - 20), InBox_Info.Input_Background, BF
  198.     END IF
  199.  
  200.  
  201.     Inbox_Software_Handle2 = _NEWIMAGE(right - left, bottom - top, 32)
  202.     Inbox_Software_Handle3 = _NEWIMAGE(right - left, 65535, 32)
  203.     Inbox_Software_Handle4 = _NEWIMAGE(right - left, 20, 32)
  204.     _DEST Inbox_Software_Handle3: _SOURCE Inbox_Software_Handle3
  205.     '******************************************  END INPUT ******************************************
  206.     Inbox_Hardware_Handle = _COPYIMAGE(InBox_Software_Handle, 33)
  207.     DIM m AS _MEM: m = _MEMIMAGE(Inbox_Software_Handle3)
  208.     DO
  209.  
  210.         IF _KEYDOWN(100307) OR _KEYDOWN(100308) THEN AltDown = -1 ELSE AltDown = 0
  211.         k = _KEYHIT
  212.         IF AltDown THEN
  213.             SELECT CASE k 'ignore all keypresses except ALT-number presses
  214.                 CASE 48 TO 57: AltWasDown = -1: alt$ = alt$ + CHR$(k)
  215.             END SELECT
  216.         ELSE
  217.             SELECT CASE k 'without alt, add any keypresses to our input
  218.                 CASE 8
  219.                     oldin$ = in$
  220.                     IF CP > 0 THEN OldCP = CP: CP = CP - 1
  221.                     in$ = LEFT$(in$, CP) + MID$(in$, CP + 2) 'backspace to erase input
  222.                 CASE 9
  223.                     oldin$ = in$
  224.                     in$ = LEFT$(in$, CP) + SPACE$(4) + MID$(in$, CP + 1) 'four spaces for any TAB entered
  225.                     OldCP = CP
  226.                     CP = CP + 4
  227.                 CASE 27
  228.                     SYSTEM
  229.                 CASE 32 TO 128
  230.                     IF _KEYDOWN(100305) OR _KEYDOWN(100306) THEN
  231.                         IF k = 118 OR k = 86 THEN
  232.                             oldin$ = in$
  233.                             in$ = LEFT$(in$, CP) + _CLIPBOARD$ + MID$(in$, CP + 1) 'ctrl-v paste
  234.                             'CTRL-V leaves cursor in position before the paste, without moving it after.
  235.                             'Feel free to modify that behavior here, if you want it to move to after the paste.
  236.                         END IF
  237.                         IF k = 122 OR k = 90 THEN SWAP in$, oldin$: SWAP OldCP, CP 'ctrl-z undo
  238.                     ELSE
  239.                         oldin$ = in$
  240.                         in$ = LEFT$(in$, CP) + CHR$(k) + MID$(in$, CP + 1) 'add input to our string
  241.                         OldCP = CP
  242.                         CP = CP + 1
  243.                     END IF
  244.                 CASE 18176 'Home
  245.                     CP = 0
  246.                 CASE 20224 'End
  247.                     CP = LEN(in$)
  248.                 CASE 21248 'Delete
  249.                     oldin$ = in$
  250.                     in$ = LEFT$(in$, CP) + MID$(in$, CP + 2)
  251.                 CASE 19200 'Left
  252.                     CP = CP - 1
  253.                     IF CP < 0 THEN CP = 0
  254.                 CASE 19712 'Right
  255.                     CP = CP + 1
  256.                     IF CP > LEN(in$) THEN CP = LEN(in$)
  257.             END SELECT
  258.         END IF
  259.         alt$ = RIGHT$(alt$, 3)
  260.         IF AltWasDown = -1 AND AltDown = 0 THEN
  261.             v = VAL(alt$)
  262.             IF v >= 0 AND v <= 255 THEN in$ = in$ + CHR$(v)
  263.             alt$ = "": AltWasDown = 0
  264.         END IF
  265.         blink = (blink + 1) MOD 30
  266.  
  267.         in$ = LEFT$(in$, maxcharacters) ' a limit, for now, of no more characters than the screen can hold
  268.         IF CP >= maxcharacters THEN CP = maxcharacters 'part of the temporary limit
  269.         _DEST Inbox_Software_Handle2: _SOURCE Inbox_Software_Handle2
  270.         CLS , 0
  271.  
  272.         _DEST Inbox_Software_Handle3: _SOURCE Inbox_Software_Handle3
  273.         CLS , 0
  274.  
  275.         COLOR InBox_Info.Input_Font_TextColor, InBox_Info.Input_Font_TextBackColor
  276.         _FONT InBox_Info.InputFont
  277.  
  278.         IF blink \ 15 THEN blinker$ = " " ELSE blinker$ = "_"
  279.  
  280.         LOCATE 1, 1: PRINT LEFT$(in$, CP) + blinker$ + MID$(in$, CP + 1);
  281.  
  282.  
  283.         _DEST Inbox_Software_Handle4: _SOURCE Inbox_Software_Handle4
  284.         CLS , 0
  285.         COLOR &HAAFFFFFF&&, &H77000000&&
  286.         char$ = "(" + _TRIM$(STR$(LEN(in$))) + "/" + _TRIM$(STR$(maxcharacters)) + ")"
  287.         _PRINTSTRING (_WIDTH(Inbox_Software_Handle4) - 8 * LEN(char$), 0), char$
  288.         Inbox_Hardware_Handle3 = _COPYIMAGE(Inbox_Software_Handle4, 33)
  289.  
  290.  
  291.         _PUTIMAGE (0, 0), Inbox_Hardware_Handle
  292.         IF CP = LEN(in$) THEN
  293.             top_visible = CP \ maxcolumns - maxrows + 1
  294.         ELSE
  295.             top_visible = (CP + 1) \ maxcolumns - maxrows + 1
  296.         END IF
  297.         IF top_visible < 0 THEN top_visible = 0
  298.  
  299.         _PUTIMAGE (0, 0)-(right, bottom), Inbox_Software_Handle3,_
  300.           Inbox_Software_Handle2, (0, top_visible * fh)-STEP(right, bottom)
  301.         Inbox_Hardware_Handle2 = _COPYIMAGE(Inbox_Software_Handle2, 33)
  302.         _PUTIMAGE (left, top)-(right, bottom), Inbox_Hardware_Handle2
  303.         _PUTIMAGE (right - _WIDTH(Inbox_Software_Handle4), bottom - 18)-STEP(_WIDTH(Inbox_Software_Handle4), 20), Inbox_Hardware_Handle3
  304.  
  305.         _DISPLAY
  306.         _LIMIT 60
  307.     LOOP UNTIL k = 13
  308.  
  309.     clean_exit:
  310.     _DEST D: _SOURCE S
  311.     _FREEIMAGE InBox_Software_Handle
  312.     _FREEIMAGE Inbox_Software_Handle2
  313.     _FREEIMAGE Inbox_Software_Handle3
  314.     _FREEIMAGE Inbox_Software_Handle4
  315.  
  316.     InBox$ = in$
  317.     EXIT SUB
  318.  
  319.     Printout:
  320.  
  321.     'This is where we print actual lines to the inbox display
  322.     FOR I = 0 TO UBOUND(WordWrap)
  323.         IF Xoffset >= 0 THEN
  324.             _PRINTSTRING (left, top + _FONTHEIGHT * I), WordWrap(I)
  325.         ELSE
  326.             l = (right - left - _PRINTWIDTH(WordWrap(I))) / 2
  327.             _PRINTSTRING (left + l, top + _FONTHEIGHT * I), WordWrap(I)
  328.         END IF
  329.     NEXT
  330.  
  331.     'update the available screen positions
  332.     top = top + _FONTHEIGHT * (UBOUND(WordWrap) + 1)
  333.  
  334.     IF EE THEN EE = 0: RETURN 'Exit Early code to avoid drawing the frame
  335.  
  336.     'draw the frame again, below the title
  337.     LINE (left, top)-(right, top + InBox_Info.FrameSize), InBox_Info.FrameColor, BF
  338.  
  339.     'update the available screen positons once again
  340.     top = top + InBox_Info.FrameSize
  341.     RETURN
  342.  
  343.  
  344. SUB InBox_Place (x AS INTEGER, y AS INTEGER)
  345.     SHARED InBox_Info AS UDT
  346.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  347.     IF x < 0 THEN
  348.         InBox_Info.X = 0
  349.         InBox_Info.Box_Justify_Hort = -1
  350.     ELSE
  351.         InBox_Info.X = x
  352.         InBox.Box_Justify_Hort = 0
  353.     END IF
  354.     IF y < 0 THEN
  355.         InBox_Info.Y = 0
  356.         InBox_Info.Box_Justify_Vert = -1
  357.     ELSE
  358.         InBox_Info.Y = y
  359.         InBox_Info.Box_Justify_Vert = 0
  360.     END IF
  361.  
  362. SUB InBox_Size (wide AS INTEGER, high AS INTEGER)
  363.     SHARED InBox_Info AS UDT
  364.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  365.     InBox_Info.Wide = wide
  366.     InBox_Info.High = high
  367.  
  368. SUB InBox_Backgrounds (Screen_background AS _INTEGER64, Box_background AS _INTEGER64)
  369.     SHARED InBox_Info AS UDT
  370.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  371.     InBox_Info.Screen_Background = Screen_background
  372.     InBox_Info.Box_Background = Box_background
  373.  
  374. SUB InBox_Frame (size AS INTEGER, kolor AS _INTEGER64)
  375.     SHARED InBox_Info AS UDT
  376.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  377.     InBox_Info.FrameColor = kolor
  378.     InBox_Info.FrameSize = size
  379.  
  380. SUB InBox_Title (font%, background&&, xOffset%, fc~&, fbg~&)
  381.     SHARED InBox_Info AS UDT
  382.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  383.     InBox_Info.TitleFont = font%
  384.     InBox_Info.Title_Background = background&&
  385.     InBox_Info.Title_Xoffset = xOffset%
  386.     InBox_Info.Title_Font_TextColor = fc~&
  387.     InBox_Info.Title_Font_TextBackColor = fbg~&
  388.  
  389. SUB InBox_Message (font%, background&&, xOffset%, fc~&, fbg~&)
  390.     SHARED InBox_Info AS UDT
  391.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  392.     InBox_Info.MessageFont = font%
  393.     InBox_Info.Message_Background = background&&
  394.     InBox_Info.Message_Xoffset = xOffset%
  395.     InBox_Info.Message_Font_TextColor = fc~&
  396.     InBox_Info.Message_Font_TextBackColor = fbg~&
  397.  
  398. SUB InBox_Input (font%, background&&, xOffset%, fc~&, fbg~&)
  399.     SHARED InBox_Info AS UDT
  400.     IF InBox_Info.Inbox_Init = 0 THEN Inbox_reset
  401.     InBox_Info.InputFont = font%
  402.     InBox_Info.Input_Background = background&&
  403.     InBox_Info.Input_Xoffset = xOffset%
  404.     InBox_Info.Input_Font_TextColor = fc~&
  405.     InBox_Info.Input_Font_TextBackColor = fbg~&
  406.  
  407.  
  408. SUB T2WWA (temp$, wide%, result() AS STRING) 'Text To Word Wrap Array
  409.     DIM BreakPoint AS STRING
  410.     BreakPoint = ",./- ;:!" 'I consider all these to be valid breakpoints.  If you want something else, change them.
  411.  
  412.     text$ = _TRIM$(temp$)
  413.     DO
  414.         'first find the natural length of the line
  415.         FOR i = 1 TO LEN(text$)
  416.             p = _PRINTWIDTH(LEFT$(text$, i))
  417.             IF p > wide% THEN EXIT FOR
  418.         NEXT
  419.         IF p < wide% THEN result(count) = RTRIM$(text$): GOTO clean_exit
  420.         lineend = i - 1
  421.         t$ = RTRIM$(LEFT$(text$, lineend)) 'at most, our line can't be any longer than what fits the screen.
  422.         FOR i = lineend TO 1 STEP -1
  423.             IF INSTR(BreakPoint, MID$(text$, i, 1)) THEN lineend = i: EXIT FOR
  424.         NEXT
  425.         result(count) = RTRIM$(LEFT$(text$, lineend))
  426.         count = count + 1
  427.         IF count > UBOUND(result) THEN REDIM _PRESERVE result(count + 100) AS STRING
  428.         text$ = LTRIM$(MID$(text$, lineend + 1))
  429.     LOOP UNTIL text$ = ""
  430.     clean_exit:
  431.     REDIM _PRESERVE result(count) AS STRING
  432.  

Best way to showcase it, is to just tell folks to give a try.  Be certain to download and have the resource files in your QB64 directory, and note  that this only works in the current DEVELOPMENT BUILD of QB64, due to me taking advantage of the new DIM syntax for testing purposes.

A couple of screenshots are below, but here's one thing to keep in mind when looking at these:


 
Inbox1.png


 
Inbox2.png


We're in a SCREEN 0 text screen, this whole time!!!

How's that for magic??
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Experimental Input Box
« Reply #5 on: February 03, 2021, 03:16:53 pm »
I'm always in SCREEN 0... Because that's where the magic happens.

I'm guessing this is similar to my SCREEN 0 scrolling text input routine, which has highlighting, cut/copy/paste, and lateral scrolling. I wanted to give yours a try, but I still haven't updated to the newest QB64 version, which allows us to use the AS UDTs. I will, at some point, because I would like to start consolidating the several new variables I'm adding to my WP, into that format. The AS UDT shortcut is a real typing saver.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Experimental Input Box
« Reply #6 on: February 03, 2021, 03:24:21 pm »
No highlighting, or copying, as I wasn’t quite shooting for an entire stand-alone text editor, but it does allow pasting and use of arrow keys to navigate forwards and backwards to make edits for typos and such.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Experimental Input Box
« Reply #7 on: February 03, 2021, 03:38:15 pm »
This is looking very impressive, I went off SmallBASIC looking for something like this way back...

I still have to test it but assume it needs dev 1.5?

Can I grab title bar and move around screen?
In case there is something underneath I need to see to input a proper answer.
« Last Edit: February 03, 2021, 03:40:42 pm by bplus »