DAY 021: LOCATE
#1
Since I'd rather code than write, I decided to present the KEYWORD of the Day, LOCATE in a brief demo. Reading the code window is also an easy option to obtain the various descriptions.

Just press a key during a pause to move on...

Code: (Select All)
' LOCATE Demo
WIDTH 100, 42
_SCREENMOVE 50, 50
'-------------------------------------------------------------------------------------------------------------
PRINT "Locate is used in text screens to locate the cursor by row and column."
PRINT: PRINT "Let's print a message at the 5th row and 2nd column of this window..."
SLEEP
LOCATE 5, 2: PRINT "Hello World!"
SLEEP
PRINT: PRINT "Locate can be used to center text. Let's center our message horizontally..."
SLEEP
msg$ = "Hello World!"
COLOR 14
LOCATE 9, _WIDTH \ 2 - LEN(msg$) \ 2: PRINT msg$
COLOR 7
PRINT: PRINT "CSRLIN denotes the current row and POS(0) for current column...";
SLEEP
LOCATE CSRLIN, POS(0): PRINT " See?..."
SLEEP
PRINT: PRINT "Just be sure you add a semi-colon to the end of your text to stay at the end of the print line."
SLEEP 6: _KEYCLEAR
PRINT: PRINT "If you are already on the row you want, you can also just leave the 1st parameter blank...";
SLEEP
LOCATE , POS(0): PRINT " See?..."
SLEEP
PRINT: PRINT "You can show or hide the cursor, too..."
SLEEP
LOCATE , , 1
PRINT: PRINT "LOCATE , , 1 where our 3rd parameter '1' means let's show the default cursor...";
SLEEP
LOCATE , POS(0), 1
PRINT: PRINT: PRINT "The two last parameters change the cursor shape: cursorStart%, cursorStop%...";
SLEEP 6
PRINT: PRINT: PRINT "The start and end parameters range from 0 to 30. Press to see a medium cursor...";
SLEEP
LOCATE , POS(0), 1, 7, 30
PRINT: PRINT: PRINT "Now press again for a thick cursor...";
SLEEP
LOCATE , POS(0), 1, 0, 30
PRINT: PRINT: PRINT "Note that '7, 7' is the default cursor and 0, 30 is full.";
SLEEP 3
PRINT: PRINT: PRINT "We can hide the cursor with '0' as the 3rd parameter. Press a key to hide it now...";
SLEEP
LOCATE , , 0
SLEEP 3: _KEYCLEAR
LOCATE , , 1
PRINT: PRINT: PRINT "And bring it back again with "; 1; " to its last state LOCATE , , 1, 0, 30...";
SLEEP
LOCATE , , 0
PRINT: PRINT: PRINT "LOCATE also has the ability to print to the last row on a VIEW PRINT restricted screen..."
VIEW PRINT 1 TO 20
SLEEP
LOCATE _HEIGHT, _WIDTH \ 2 - LEN(msg$) \ 2: PRINT msg$;
SLEEP
VIEW PRINT: CLS
PRINT "Finally we need to note some behavior that could screw up your printing.";
SLEEP 4
PRINT: PRINT: PRINT "LOCATE may wrap some text but mostly prints an entire text line to next line...";
LOCATE , , 1, 0, 30
SLEEP
LOCATE , , 0 ' Hide cursor.
PRINT "See? I'm on the next line this time."
SLEEP 6
PRINT: PRINT "This next demo will show what happens when printing an '*' to the last row and column..."
SLEEP
WIDTH 80, 25
CLS
LOCATE 15, 1: PRINT "HEIGHT ="; _HEIGHT, "WIDTH ="; _WIDTH
PRINT: PRINT "Printing an '*' to the right bottom corner with a semi colon works,"
PRINT: PRINT "but look where the next cursor row is."
LOCATE _HEIGHT, _WIDTH
COLOR 14 + 16: PRINT "*";: COLOR 7
y = CSRLIN: x = POS(0)
LOCATE 17: PRINT "Current cursor row is"; y; "instead of"; y + 1; "and the"
PRINT: PRINT "cursor column is"; x; "as expected."
SLEEP
LOCATE y, 1: PRINT "Here's where the next line of text will appear if you don't code a solution."
PRINT: PRINT "See? it's above the asterisk!...";
SLEEP
CLS
PRINT: PRINT "Our final demo will show how to overcome this restriction"
PRINT: PRINT "When trying to fill the screen..."
SLEEP
CLS
a$ = STRING$(_WIDTH, "*")
FOR i = 1 TO _HEIGHT
    PRINT a$;
NEXT
SLEEP
CLS
PRINT "Well that didn't work. The last row was empty because the screen scrolled."
PRINT: PRINT "Hmm, let's use LOCATE to fix that..."
SLEEP
CLS
a$ = STRING$(_WIDTH, "*")
FOR i = 1 TO _HEIGHT
    LOCATE i, 1 ' <---------------------------Fixes scrolling issue.
    PRINT a$;
NEXT
SLEEP
CLS
PRINT "Yep, that worked..."
_DELAY 1
msg$ = "That concludes this portion of our KEYWORD for the Day!"
LOCATE _HEIGHT \ 2, _WIDTH \ 2 - LEN(msg$) \ 2: PRINT msg$
END

Now naturally I did this for SCREEN 0. If anyone wants to elaborate on the use of LOCATE in a graphics environment, feel free.

Pete
Reply
#2
Before I do much explaining, copy and run the code below so you can see what I'm talking about for yourself:

Code: (Select All)
Screen _NewImage(800, 600, 32)
f = _LoadFont("cour.ttf", 16, "monospace")
f1 = _LoadFont("cour.ttf", 16)

_Font f
Locate 10, 10: Print "FONT F, MONOSPACE"

_Font f1
Locate 11, 10: Print "FONT F1, NO-MONOSPACE"

sleep


Now, LOCATE works *EXACTLY* the same in graphics mode as it does in Pete's SCREEN 0 example -- *as long as you're dealing with a monospace font*!

Font F, in the example above, is monospaced and thus locates 10 rows down and 10 columns over.  It starts printing just where we'd expect to see it.

Font F1, on the other hand, is a variable-width font (we didn't specify the "monospace" tag with it), and as such, it has a _FONTWIDTH of 0 (ZERO!).  There's no way we can figure out where to put the font in regards to the "10th column of text", as it's variable width.  10th column of what??  i's or W's?  When the w's of many variable width fonts are easily twice the width of the i's, you can't know where the 10th column of anything is going to be -- the 10th letter of your text will start wherever the width of the previous 9 characters place it!  Tongue

So how does LOCATE work with variable width fonts??

It still locates by ROW, which is why the !! in that LOCATE 11, 10 ends up placing us exactly one line below the LOCATE 10, 10 we used previously.  The difference is, it no longer locates by COLUMN, but instead by PIXEL.

For a fixed width (monospace) font, LOCATE works by ROW, COLUMN.
For a variable width font (no monospace), LOCATE works by ROW, PIXEL.


And that's basically the difference in LOCATE with a graphical environment, verses a SCREEN 0 environment.  In SCREEN 0, one doesn't have to worry about how locate acts with variable width fonts, as they're simply not allowed in screen 0 to begin with.

It's only in graphic modes, and with non-monospaced fonts, that one has to remember that LOCATE works by ROW, PIXEL.  In all other cases, it work via ROW, COLUMN.
Reply
#3
"Try doing that with LOCATE," said a mini-mod of the oldest forum. Now I'm trying to think about why he said it...

OK I'm giving the game away. I shared a game program that I wrote on QuickBASIC, kept it at the "tiny" 320x200 but it was mostly text mode anyway. The time hasn't arrived yet where I tell you what was my username in Galleon's forum and other things about it.

Hmmm did some of you look for "Discussion" posts in the large number of pages of the old QB64 Wiki? Some of it was entertaining, very surprising coming in one half from somebody who later became very important...

Umm, erm, ahh... the third parameter of "LOCATE" is more useful now in Freebasic than in QB64, because the other programming system takes up the terminal that an user program is run in, assuming it's not a "GUI" program. Not like QB64 "SCREEN 0" nor like "$CONSOLE:ONLY" mode. A few people would request the fourth and fifth parameters honored only to keep freaking out at the moving hamburger...

(12-02-2022, 05:41 AM)SMcNeill Wrote: And that's basically the difference in LOCATE with a graphical environment, verses a SCREEN 0 environment.  In SCREEN 0, one doesn't have to worry about how locate acts with variable width fonts, as they're simply not allowed in screen 0 to begin with.

It's only in graphic modes, and with non-monospaced fonts, that one has to remember that LOCATE works by ROW, PIXEL.  In all other cases, it work via ROW, COLUMN.
Arrow Maybe I should spend far more time reading the wise people than babbling.
Reply




Users browsing this thread: 2 Guest(s)