Author Topic: Hey graphic gurus, top this!!!  (Read 3890 times)

0 Members and 1 Guest are viewing this topic.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Hey graphic gurus, top this!!!
« on: August 15, 2021, 09:15:17 pm »
Going through some age old QB4.5 stuff I made during the Jurassic Period, and I came across this little ge I used back then to get a cursor effect in SCREEN 12. So is there a better way now in QB64?

Code: QB64: [Select]
  1. startpos% = 5
  2. word$ = "This is a demo of a flashing cursor for a graphics screen."
  3. LOCATE 5, startpos%: PRINT word$;
  4.  
  5. cur$ = "_"
  6. z1 = TIMER
  7.     flag = 0
  8.     _LIMIT 30
  9.     b$ = INKEY$
  10.     IF b$ = CHR$(27) THEN SYSTEM
  11.  
  12.     IF LEN(b$) THEN
  13.         IF b$ = CHR$(0) + "R" THEN
  14.             IF cur$ = "_" THEN
  15.                 cur$ = CHR$(219)
  16.             ELSE
  17.                 cur$ = "_"
  18.             END IF
  19.         END IF
  20.  
  21.         IF b$ = CHR$(0) + "K" THEN
  22.             IF POS(0) > startpos% THEN
  23.                 GOSUB reprint
  24.                 LOCATE , POS(0) - 1
  25.             ELSE
  26.                 flag = 0
  27.             END IF
  28.         END IF
  29.  
  30.         IF b$ = CHR$(0) + "M" THEN
  31.             IF POS(0) < startpos% + LEN(word$) THEN
  32.                 flag = 1
  33.                 GOSUB reprint
  34.             ELSE
  35.                 flag = 0
  36.             END IF
  37.         END IF
  38.  
  39.     END IF
  40.  
  41.     IF ABS(z1 - TIMER) > .4 OR flag THEN
  42.         SELECT CASE cursor
  43.             CASE 0
  44.                 cursor = -1
  45.                 PRINT cur$;
  46.                 LOCATE , POS(0) - 1
  47.             CASE -1
  48.                 cursor = 0
  49.                 GOSUB reprint
  50.         END SELECT
  51.         z1 = TIMER
  52.     END IF
  53.  
  54. reprint:
  55. c$ = MID$(word$, POS(0) - (startpos% - 1), 1)
  56. IF c$ = "" THEN PRINT " "; ELSE PRINT c$;
  57. IF flag <> 1 THEN LOCATE , POS(0) - 1
  58. flag = -1
  59.  


Use arrow left and right, or press Insert key to change from a line to a full block cursor.

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

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #1 on: August 15, 2021, 10:47:06 pm »
Could probably do this before:
Code: QB64: [Select]
  1. start = 5
  2. word$ = "This is a demo of a flashing cursor for a graphics screen."
  3. Locate 5, start: Print word$;
  4. On Timer(.4) GoSub cursim
  5. cur = start + Len(word$)
  6.     b$ = InKey$
  7.     If b$ = Chr$(27) Then
  8.         System
  9.     ElseIf b$ = Chr$(0) + "R" Then
  10.         insert = 1 - insert
  11.     ElseIf b$ = Chr$(0) + "K" Then
  12.         If cur > start Then cur = cur - 1
  13.     ElseIf b$ = Chr$(0) + "M" Then
  14.         If cur < start + Len(word$) Then cur = cur + 1
  15.     End If
  16.     _Limit 20
  17. cursim:
  18. If insert Then c$ = Chr$(219) Else c$ = "_"
  19. blink = 1 - blink
  20. If blink Then Locate , cur: Print c$; Else Locate 5, start: Print word$; " ";
  21.  
« Last Edit: August 15, 2021, 10:52:12 pm by bplus »

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #2 on: August 16, 2021, 03:22:43 am »
Same method... just more optimistic! :D

What's funny is using SELECT CASE instead of IF/THEN/ELSE actually would have added one extra line.

Anyway, optimization aside, and that was a nice job, btw, I'm still wondering if anyone has devised, or if QB64 has a native way, of putting a working cursor into a graphics word processor, other than this???

Pete

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

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #3 on: August 16, 2021, 01:19:33 pm »
If graphic mode cursor, so why LOCATE? Oh i see, it is program created using QB4.5!

So here is my version (modified @bplus version), it calculate graphics coordinates from text coordinates and then use _PRINTSTRING.

Code: QB64: [Select]
  1. start = 5
  2. word$ = "This is a demo of a flashing cursor for a graphics screen."
  3. LOCATE 5, start: PRINT word$;
  4. StartGraphicX = _FONTWIDTH * (POS(_DEST) - LEN(word$) - 1)
  5. StartGraphicY = _FONTHEIGHT * CSRLIN - (_FONTHEIGHT)
  6. CursorY = _FONTHEIGHT * CSRLIN - (_FONTHEIGHT - 2) 'draw cursor two pixels under text
  7.  
  8. ON TIMER(.08) GOSUB cursim
  9. cur = start + LEN(word$)
  10.  
  11.     b$ = INKEY$
  12.     IF b$ = CHR$(27) THEN
  13.         SYSTEM
  14.     ELSEIF b$ = CHR$(0) + "R" THEN
  15.         insert = 1 - insert
  16.     ELSEIF b$ = CHR$(0) + "K" THEN
  17.         IF cur > start THEN cur = cur - 1
  18.     ELSEIF b$ = CHR$(0) + "M" THEN
  19.         IF cur < start + LEN(word$) THEN cur = cur + 1
  20.     END IF
  21.     _LIMIT 20
  22. cursim:
  23. CursorX = _FONTWIDTH * (cur - 1)
  24. IF blink THEN c$ = " " ELSE c$ = "_"
  25. blink = 1 - blink
  26.  
  27. _PRINTSTRING (StartGraphicX, StartGraphicY), word$ + " "
  28. IF blink THEN _PRINTSTRING (CursorX, CursorY), c$
  29.  

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #4 on: August 16, 2021, 01:48:44 pm »
Or faster:

Code: QB64: [Select]
  1. start = 5
  2. word$ = "This is a demo of a flashing cursor for a graphics screen."
  3. LOCATE 5, start: PRINT word$;
  4. StartGraphicX = _FONTWIDTH * (POS(_DEST) - LEN(word$) - 1)
  5. StartGraphicY = _FONTHEIGHT * CSRLIN - (_FONTHEIGHT)
  6. CursorY = _FONTHEIGHT * CSRLIN - (_FONTHEIGHT - 2) 'draw cursor two pixels under text
  7. StartTime = TIMER + .4
  8.  
  9. cur = start + LEN(word$)
  10.  
  11.     b$ = INKEY$
  12.     IF b$ = CHR$(27) THEN
  13.         SYSTEM
  14.     ELSEIF b$ = CHR$(0) + "R" THEN
  15.         insert = 1 - insert
  16.         GOSUB cursim
  17.     ELSEIF b$ = CHR$(0) + "K" THEN
  18.         IF cur > start THEN cur = cur - 1: GOSUB cursim
  19.     ELSEIF b$ = CHR$(0) + "M" THEN
  20.         IF cur < start + LEN(word$) THEN cur = cur + 1: GOSUB cursim
  21.     END IF
  22.     IF TIMER > StartTime THEN
  23.         StartTime = TIMER + .4
  24.         GOSUB cursim
  25.     END IF
  26.  
  27.     _PRINTSTRING (StartGraphicX, StartGraphicY), word$ + " "
  28.     IF blink THEN _PRINTSTRING (CursorX, CursorY), c$
  29.     _LIMIT 20
  30.  
  31. cursim:
  32. CursorX = _FONTWIDTH * (cur - 1)
  33. IF blink THEN c$ = " " ELSE c$ = "_"
  34. blink = 1 - blink
  35.  

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #5 on: August 16, 2021, 03:12:22 pm »
Cool! You got the cursor to move under the characters, without the characters swapping out with the cursor (my blinking effect for when the cursor was under a character). That's a performance improvement on top of Mark's optimization improvement.

Oh wait, the insert wasn't completed in your example, so we can't change the cursor to a block by pressing the Insert key....

This part:

    ELSEIF b$ = CHR$(0) + "R" THEN
        insert = 1 - insert
        GOSUB cursim

So if you could add a way to show the cursor as a block instead of an underscore, when the Inert key is press once, that would be amazing, but I wonder if there is a way the block cursor could be made translucent, like it is in a SCREEN 0 app? Again, my approach in the old days was to swap out the letter characters with the block character to make an alternating blinking cursor and letter effect.

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

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #6 on: August 16, 2021, 03:35:00 pm »
In 32 color mode:
Code: QB64: [Select]
  1. Screen _NewImage(800, 600, 32)
  2. start = 5
  3. word$ = "This is a demo of a flashing cursor for a graphics screen."
  4. Locate 5, start: Print word$;
  5. On Timer(.4) GoSub cursim
  6. cur = start + Len(word$)
  7.     b$ = InKey$
  8.     If b$ = Chr$(27) Then
  9.         System
  10.     ElseIf b$ = Chr$(0) + "R" Then
  11.         insert = 1 - insert
  12.     ElseIf b$ = Chr$(0) + "K" Then
  13.         If cur > start Then cur = cur - 1
  14.     ElseIf b$ = Chr$(0) + "M" Then
  15.         If cur < start + Len(word$) Then cur = cur + 1
  16.     End If
  17.     _Limit 20
  18. cursim:
  19. If insert Then c$ = Chr$(219): Else c$ = "_"
  20. Locate 5, start: Print word$; " ";
  21. blink = 1 - blink
  22. If blink Then
  23.     Color _RGB32(255, 255, 255, 160), 0
  24.     Locate 5, cur: Print c$;
  25.     Color &HFFFFFFFF
  26.  

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #7 on: August 16, 2021, 03:45:39 pm »
INSERT key supported now:


Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 240, 32)
  2. start = 5
  3. word$ = "This is a demo of a flashing cursor for a graphics screen."
  4. LOCATE 5, start: PRINT word$;
  5. StartGraphicX = _FONTWIDTH * (POS(_DEST) - LEN(word$) - 1)
  6. StartGraphicY = _FONTHEIGHT * CSRLIN - (_FONTHEIGHT)
  7. CursorY = _FONTHEIGHT * CSRLIN - (_FONTHEIGHT - 2) 'draw cursor two pixels under text
  8. StartTime = TIMER + .4
  9.  
  10. cur = start + LEN(word$)
  11.  
  12.     b$ = INKEY$
  13.     IF b$ = CHR$(27) THEN
  14.         SYSTEM
  15.     ELSEIF b$ = CHR$(0) + "R" THEN
  16.         insert = 1 - insert
  17.         GOSUB cursim
  18.     ELSEIF b$ = CHR$(0) + "K" THEN
  19.         IF cur > start THEN cur = cur - 1: GOSUB cursim
  20.     ELSEIF b$ = CHR$(0) + "M" THEN
  21.         IF cur < start + LEN(word$) THEN cur = cur + 1: GOSUB cursim
  22.     END IF
  23.     IF TIMER > StartTime THEN
  24.         StartTime = TIMER + .4
  25.         GOSUB cursim
  26.     END IF
  27.  
  28.  
  29.     _PRINTSTRING (StartGraphicX, StartGraphicY), word$ + " "
  30.  
  31.  
  32.     COLOR _RGB32(255)
  33.     IF insert THEN c$ = CHR$(219)
  34.     IF insert AND blink THEN COLOR _RGBA32(255, 255, 255, 127): _PRINTSTRING (CursorX, StartGraphicY), c$: _LIMIT 20: _CONTINUE 'character Å° is printed to the same coordinates as word$ characters
  35.     IF insert AND NOT blink THEN COLOR _RGB32(255): _PRINTSTRING (CursorX, StartGraphicY), c$: _LIMIT 20: _CONTINUE
  36.     IF blink THEN _PRINTSTRING (CursorX, CursorY), c$
  37.     _LIMIT 20
  38.  
  39. cursim:
  40. CursorX = _FONTWIDTH * (cur - 1)
  41. IF blink THEN c$ = " " ELSE c$ = "_"
  42. blink = 1 - blink
  43.  

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #8 on: August 16, 2021, 04:27:55 pm »
Wow, we're certainly getting somewhere with this. I do know my system is the slowest of the bunch here, and as such, the CLS in Mark's example makes the sentence jump around a bit. Also, the arrow keys are not quite as smooth. The translucent cursor appearance, however, is reMarkable! I wish the QB64 IDE switched to it.

While Petr is twice as much code, the absence of CLS makes it so there is no jittery effects on my slow-ascii system and the arrow keys create a smooth movement, better than my initial SCREEN 12 example. I'm not sure if the cursor could be made to look like the effect mark posted, or not. I tried to fiddle with a marriage between the two, but since graphics isn't my thing, I came up empty.

Now if SCREEN 0 didn't have a native cursor, I'd make a more complex version of this tiny demo:

Code: QB64: [Select]
  1. LOCATE 5, 5
  2. PRINT "This is a flashing block cursor example in SCREEN 0."
  3. LOCATE 5, 24
  4.     COLOR 0, 7: PRINT "b";: LOCATE , POS(0) - 1
  5.     _DELAY .4
  6.     COLOR 7, 0: PRINT "b";: LOCATE , POS(0) - 1
  7.     _DELAY .4

Of course with any build we have to consider printing to the far right edge of the screen (screws with locate) or for a block cursor, especially the one I coded above, what the appearance will be over color or especially already highlighted text.

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

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #9 on: August 16, 2021, 11:24:50 pm »
For 32 bit screens and a more advanced font:

Code: QB64: [Select]
  1. DEFLNG A-Z
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3. f& = _LOADFONT("liberati.ttf", 16)
  4. x = 100
  5. y = 100
  6. maxchars = 60
  7. _PRINTSTRING (x, y + 99), "Ins, Del, Home, End, arrow keys and Esc active."
  8. z$ = GetField("Mary had a little lamb, some peas, and a salad.", x, y, maxchars)
  9. COLOR Black, White
  10. _PRINTSTRING (x, y + 40), z$
  11.  
  12. FUNCTION GetField$ (t$, x, y, maxchars)
  13.     DIM a, i, p, tx, c$
  14.     t$ = LEFT$(t$ + SPACE$(maxchars), maxchars)
  15.     p = 1
  16.     DO: _LIMIT 20
  17.         tx = x
  18.         LINE (x, y)-(x + _PRINTWIDTH(t$) + 20, y + 16), _RGB32(0), BF
  19.         FOR i = 1 TO maxchars
  20.             c$ = MID$(t$, i, 1)
  21.             COLOR White, _RGB32(0, 0, 0, 0)
  22.             IF i = p THEN
  23.                 sx = x
  24.                 IF TIMER > cc! THEN
  25.                     bit = bit XOR 1
  26.                     cc! = TIMER + .2
  27.                 END IF
  28.                 IF insertmode THEN
  29.                     LINE (tx, y)-(tx + _PRINTWIDTH(c$), y + 16), _RGB32(bit * 200), BF ' insert cursor
  30.                     IF bit THEN COLOR Black, _RGB32(0, 0, 0, 0) '                        black on zip
  31.                 ELSE
  32.                     LINE (tx, y + 16)-STEP(_PRINTWIDTH(c$), 0), _RGB32(bit * 200) '      underline cursor
  33.                 END IF
  34.             END IF
  35.             _PRINTSTRING (tx, y), c$
  36.             tx = tx + _PRINTWIDTH(c$)
  37.         NEXT i
  38.         _DISPLAY '                                                                       text and cursor
  39.         COLOR White, Black '                                                             regular colors
  40.         _PRINTSTRING (x, y), t$ '                                                        text only, preparing for Enter
  41.         i$ = INKEY$
  42.         SELECT CASE LEN(i$)
  43.             CASE IS = 1
  44.                 IF i$ = CHR$(27) THEN SYSTEM '                                           Esc
  45.                 IF i$ = CHR$(13) THEN '                                                  Enter
  46.                     GetField$ = LTRIM$(RTRIM$(t$))
  47.                     _DISPLAY
  48.                     _AUTODISPLAY
  49.                     EXIT FUNCTION
  50.                 END IF
  51.                 IF i$ = CHR$(8) THEN '                                                   backspace
  52.                     p = p - 1 - (p = 1)
  53.                     t$ = LEFT$(t$, p - 1) + RIGHT$(t$, maxchars - p) + " "
  54.                     _CONTINUE
  55.                 END IF
  56.                 IF insertmode THEN
  57.                     t$ = LEFT$(LEFT$(t$, p - 1) + i$ + RIGHT$(t$, LEN(t$) - p + 1) + SPACE$(10), maxchars)
  58.                 ELSE
  59.                     MID$(t$, p, 1) = i$
  60.                 END IF
  61.                 p = p + 1
  62.                 IF p > maxchars THEN p = maxchars: SOUND 4444, 1
  63.             CASE IS = 2
  64.                 a = ASC(RIGHT$(i$, 1))
  65.                 IF a = 71 THEN p = 1 '                                                   Home
  66.                 IF a = 79 THEN p = LEN(RTRIM$(t$)) + 1 '                                 End
  67.                 IF a = 82 THEN insertmode = insertmode XOR 1 '                           Ins
  68.                 IF a = 83 THEN t$ = LEFT$(t$, p - 1) + RIGHT$(t$, maxchars - p) + " " '  Del
  69.                 p = p + (a = 75) - (a = 77) '                                            left or right arrow
  70.                 IF p < 1 THEN p = 1
  71.                 IF p > maxchars THEN p = maxchars
  72.         END SELECT
  73.     LOOP
  74.  
  75.  
« Last Edit: August 16, 2021, 11:34:08 pm by Richard Frost »
It works better if you plug it in.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #10 on: August 17, 2021, 10:36:16 am »
@Richard Frost

Nice works fine without the font. This looks better than Pete spec'd as long as doesn't give him the jitters. ;-))

I could use this over my graphics Input fix, better cursor.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Hey graphic gurus, top this!!!
« Reply #11 on: August 17, 2021, 03:22:46 pm »
@Richard Frost : Very nice! I see it's limited to 32-color use. I'm not sure how that would effect all users. It's very smooth and looks exactly like a SCREEN 0 cursor routine.

I think it works with the block cursor like the example I showed where the background and foreground colors get swapped in a time loop. The only problem I see here is a user always needs a blank space at the end of the sentence, or the cursor disappears. You can see that by trying my stripped down version of it, below...

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 600, 32)
  2. x = 100 ' start column
  3. y = 100 ' start row
  4. sentence$ = "This is a demo of a flashing cursor for a graphics screen."
  5. maxchars = LEN(sentence$)
  6. z$ = GetField(sentence$, x, y, maxchars)
  7. COLOR Black, White
  8. _PRINTSTRING (x, y + 40), z$
  9.  
  10. FUNCTION GetField$ (t$, x, y, maxchars)
  11.     t$ = LEFT$(t$ + SPACE$(maxchars), maxchars)
  12.     DO: _LIMIT 20
  13.         tx = x
  14.         LINE (x, y)-(x + _PRINTWIDTH(t$) + 20, y + 16), _RGB32(0), BF
  15.         FOR i = 1 TO maxchars
  16.             c$ = MID$(t$, i, 1)
  17.             COLOR White, _RGB32(0, 0, 0, 0)
  18.             IF i = POS(0) THEN
  19.                 sx = x
  20.                 IF TIMER > cc! THEN
  21.                     bit = bit XOR 1
  22.                     cc! = TIMER + .2
  23.                 END IF
  24.                 IF insertmode THEN
  25.                     LINE (tx, y)-(tx + _PRINTWIDTH(c$), y + 16), _RGB32(bit * 200), BF ' insert cursor
  26.                     IF bit THEN COLOR Black, _RGB32(0, 0, 0, 0) '                        black on zip
  27.                 ELSE
  28.                     LINE (tx, y + 16)-STEP(_PRINTWIDTH(c$), 0), _RGB32(bit * 200) '      underline cursor
  29.                 END IF
  30.             END IF
  31.             _PRINTSTRING (tx, y), c$
  32.             tx = tx + _PRINTWIDTH(c$)
  33.         NEXT i
  34.         _DISPLAY ' text and cursor
  35.         COLOR White, Black ' default colors
  36.         _PRINTSTRING (x, y), t$
  37.         i$ = INKEY$
  38.         SELECT CASE LEN(i$)
  39.             CASE IS = 1
  40.                 IF i$ = CHR$(27) THEN SYSTEM
  41.                 IF insertmode THEN
  42.                     t$ = LEFT$(LEFT$(t$, POS(0) - 1) + i$ + RIGHT$(t$, LEN(t$) - POS(0) + 1), maxchars)
  43.                 ELSE
  44.                     MID$(t$, POS(0), 1) = i$
  45.                 END IF
  46.             CASE IS = 2
  47.                 IF RIGHT$(i$, 1) = "M" THEN LOCATE , POS(0) + 1 ' No limiter added yet!
  48.                 IF RIGHT$(i$, 1) = "K" THEN if pos(0)> 1 then LOCATE , POS(0) - 1
  49.                 IF ASC(RIGHT$(i$, 1)) = 82 THEN insertmode = insertmode XOR 1 ' Ins
  50.         END SELECT
  51.     LOOP
  52.  


Notes:

I did not make a way to stop the left and right cursor movement.

I replaced the "p" variable with pos(0). It works, but it would need a limitation using maxchars if a way to get the cursor showing after the last character of the sentence is figured out.


Pete

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