User Tools

Site Tools


logo:tutorial:chapter8

Chapter 8: Interacting with the User

A program that just runs all by itself can be a useful thing. However, a program that interacts with the user is often much more interesting and flexible because it may not do the same thing every time, depending on the choices that the user makes. There are Logo commands, described in the Reference Manual, that let you get information from the user through the Listener window. Look up READ, READCHAR, READWORD and READLIST, for examples. This chapter describes the graphical controls available in Logo.

Controls in General

Graphical controls are used to create a Graphical User Interface (or GUI presentation) for an application program. The idea of “control” is from two points of view: (1) GUI controls help a program control the actions of a user by restricting choices and limiting selections to those defined and understood by the application to prevent a user from supplying data that does not compute; and (2) GUI controls allow users to pick and choose which options they want when they want them - controls give users a sense of power over the application instead of being controlled by it.

Eight different controls are available in the Controls panel of the Toolbox. In addition, you can select New Graphics Window from the File menu. This is often helpful to keep controls and drawings separated.

Controls are graphical and they respond to many of the same commands that you use for bitmaps and turtles, but they are not bitmaps or turtles. Controls have a Z.ORDER property, but they don't use it in the same way that bitmaps and turtles use it. Controls always appear on top of the bitmaps and turtles, regardless of the layer number they are on. And, controls can be placed on top of each other, but the Z.ORDER number has nothing to do with which one is on top - that depends on which one was clicked last. So, you can ignore the Z.ORDER for controls - just remember that controls are always on top.

Controls can be dragged from the Controls panel of the Toolbox to the Graphics window. Each control created in this way is given a name based on its type. For example, open the Controls panel and drag out a button control and drop it on the Graphics window. Logo displays the message:

BUTTON.1 dropped.

When you drag a control to the Graphics window, some properties are filled in with default values. For example, the “Click me” label on the button is really the value of the button's TEXT property. Other controls have different defaults, depending on the control. The NEW and DECLARE commands can be used to create controls. The NEW command creates a control with a name like the one created by dragging a control from the Toolbox. The DECLARE command requires that you choose a name. In either case, the control is placed at the center of the Graphics window without the default values that are assigned when you drag a control from the Toolbox. Type:

NEW "BUTTON
Result: BUTTON.2

To move a control to a new location, hold down the Shift key while you click and drag on the control. You can also move a control by setting the POSITION property to a new coordinate point. Type:

PPROP "BUTTON.2 "POSITION [100 100]

Each type of control is a different classification. Type:

ASK EVERY "BUTTON [BACK 50]

You can get rid of a control with the ERASE command. Type:

ERASE "BUTTON.2

Be careful with the CLEARSCREEN command (CS) - it erases all of the controls from the Graphics window. Use CLEAN or DRAW unless you really want to get rid of the controls.

Chances are, you've used every type of control in some application or other, so you know how they work from the user's point of view. Now, you'll learn what it takes to put them into your own programs. It's not difficult - most things are done with manipulations of the property lists. The most important common properties are NAME, POSITION, SIZE and RUN. Except for the scrollbar control, TEXT is another common property but it's not used in the same way by each control. Some controls have special properties as well as their own commands.

Button Control

The button control is typically used to run something. When you click on a button, you expect something to happen. Type:

EDP "BUTTON.1

The properties dialog for controls is not affected by the setting of the Extended property lists option of the Preferences dialog of the Edit menu. You always see the extended properties dialog. Of course, you can right-click (on a PC) or Ctrl-click (on a Mac) to bring up the properties dialog display, too. Change the following properties to the value shown:

RUN	change to [MOVE]
SIZE	change to [50 50]
TEXT	change to Move

The TEXT property of a button is the label you see on it. It's a good idea to use short but meaningful words for labels. By default, a button is a long rectangle but it doesn't have to be. When you click on the button control, the instructions in the RUN property are run as if you had typed them in the Listener window. Click OK to close the dialog and then define the MOVE procedure.

TO MOVE
	FORWARD 100 RIGHT 123
END

Click on the Move button a few times. You should see the turtle move and turn each time you click on the button.

Checkbox Control

The checkbox control is like a switch - it's either on or off. Typically, a checkbox gives the user a choice between two conditions. Drag out a checkbox control and place it next to the Move button. Change the following properties to the value shown:

RUN	change to [SWITCH.PEN]
SIZE	change to [50 50]
TEXT	change to Trail

In your program, it's usually best to have a procedure that outputs the value of a control. A procedure with a meaningful name allows you to think in terms of what a control is for rather than how you have to manipulate it. Define the following procedure:

TO TRAIL?
	GPROP "CHECKBOX.1 "STATE
END

For a checkbox control, the value is from the STATE property. The TEXT property is just a label. You can put a lot of instructions in the RUN property of a control, but using a procedure is easier to deal with, especially if you need to make changes later on. Define the following procedure:

TO SWITCH.PEN
	IF TRAIL? [PENDOWN] [PENUP]
END

This form of the IF command has two lists of instructions that may be run, depending on the result of the condition being tested. In this case, the condition is the output of the TRAIL? procedure - it outputs either TRUE or FALSE. The first list is run if the condition is true; the second list is run if the condition is false.

Now, when you click on the Move button, the Trail checkbox will determine whether or not the turtle leaves a trail (or draws lines). The checkmark indicates that a condition has been selected or turned on; removing the checkmark turns off the selection.

Radiobutton Control

The radiobutton control is a simulation of a mechanical button - like a channel selector on some radios. When you push on a real radiobutton, it selects a channel. To change channels, you have to push on a different radiobutton - pushing on the same radiobutton has no effect. This type of selection is called “mutually exclusive” in statistics - you can have one or the other, but not both at the same time.

Drag out two rabiobutton controls and place them next to the Trail checkbox, one above the other. Change the following properties of RAIDIOBUTTON.1:

	RUN 	change to [CHANGE.COLOR 1]
	TEXT	change to Red

Change the following properties of RADIOBUTTON.2:

	RUN		change to [CHANGE.COLOR 2]
	TEXT	change to Black

Both radiobuttons run the same procedure, but they give it a different input to identify themselves. The CHANGE.COLOR procedure has to do two things: turn off the other radiobutton and then change the color of the turtle's pen to the requested color. It's best to turn off the other button before doing anything else; otherwise, there may be a slight delay - and you might think your radio is broken. Define the CHANGE.COLOR procedure:

TO CHANGE.COLOR :BUTTON
	IF :BUTTON = 1 [TURN.OFF 2 SETPC "RED]
	IF :BUTTON = 2 [TURN.OFF 1 SETPC "BLACK]
END

The TURN.OFF procedure takes a button number as input. Using the WORD command to build the actual name of the radiobutton, it then sets the STATE property to FALSE, which simulates popping the button out. Define TURN.OFF:

TO TURN.OFF :BUTTON
	PPROP WORD "RADIOBUTTON. :BUTTON "STATE "FALSE
END

Editbox Control

The editbox control is for getting information from users. It's normally a free-form input which means users can type whatever they want. You can control this, to some extent, by using the FILTER property. Just put in the characters you consider to be acceptable. For example, if you want numeric input only, then put the string of digits 0123456789 in the FILTER property to restrict the users' input to just numbers.

A maximum of 255 characters can be entered into an editbox. You can control this with the LIMIT property. It can be any number from 1 to 255.

How will your program know if a user has entered anything in an editbox control? The MODIFIED property gets set to “TRUE whenever the user types anything into the editbox. It does not get set to FALSE again. However, your program can set MODIFIED to FALSE after getting the TEXT value so that it can detect a new entry later on.

Since user input is (believe it or don't) a very unreliable way of getting accurate data, be careful about what you expect to get from a user in an editbox control. The user's name is not likely to cause a problem, but don't ask a user to enter a command line to run - there's a good chance your program will stop with an error message.

Statictext (Textbox) Control

The statictext (or textbox) control is typically used for displaying helpful information for the user, either as the label for a control or as an instruction panel. Drag out a statictext control and change the following property:

	TEXT	change to Velocity

Put three spaces in front of the word to make it appear more centered. This control will be used as the label for a scrollbar, since it doesn't have a label of its own.

Scrollbar Control

The scrollbar control (also called a slider) is used to get numeric input from a user. You can control the range of values with the MINIMUM and MAXIMUM properties to make sure the number you get is always in the proper range. The arrows at the ends of a scrollbar adjust the value of the control in small increments, as defined by the SMALLINC property. The LARGEINC property is used to adjust the scrollbar value when the user clicks in the areas between the arrows and the sliding mechanism. The position of the sliding mechanism of a scrollbar is a visual representation of the control's value as it relates to the minimum and maximum values allowed.

The scrollbar does not have TEXT property. You can use a statictext control as a label. However, if you have checked the Show Hints option of the Help menu, you can see the value of the TOOLTIP property when you put the mouse pointer over a scrollbar. The value of a scrollbar is the VALUE property. It may not be a whole number, even though the minimum, maximum and increments are whole numbers, because the sliding mechanism can be moved to any position between the arrows.

Drag out a scrollbar control, place it under the “Velocity” label, and change the following property:

	RUN	change to [CHANGE.VELOCITY]

Define the following procedure that outputs the value of the scrollbar:

TO CURRENT.VELOCITY
	GPROP "SCROLLBAR.1 "VALUE
END

The CHANGE.VELOCITY procedure will do two things: set the turtle's velocity to the value of the scrollbar and display the current velocity in another statictext control. Drag out another statictext control, place it next to the “Velocity” label, and change the following property:

	SIZE	change to [20 16]

Use shift-drag to move the new statictext control close to the “Velocity” label. Now, define the CHANGE.VELOCITY procedure:

TO CHANGE.VELOCITY
	SETVELOCITY CURRENT.VELOCITY
	PPROP "STATICTEXT.2 "TEXT ROUND CURRENT.VELOCITY
END

The ROUND command takes a number as input and outputs a whole number. For example, if the input is 33.5, the output is 34; if the input is 22.4, the output is 22.

ListBox Control

Drag a listbox control from the Toolbox and place it under the scrollbar control. The listbox control is actually a table of text items. When you drag a listbox to the Graphics window, there are three items in the table, although you probably won't want to use them. An easy way to get rid of them is to ask the listbox to remove them for you. Type:

REPEAT 3 [ASK "LISTBOX.1 [REMOVE 0] ]

REMOVE is one of six special commands that are used by the listbox and popup controls. It takes an index number as input and removes the associated item from the table. Index number 0 is for the first item in the table. When it is removed, the other items move up - index number 1 becomes the new index number 0, and so on.

The APPEND command adds a new item to the end of the table. Type:

ASK "LISTBOX.1 [APPEND "HOME]
Result: 0

The output of APPEND is the index number of the item that was added. If you don't need to use it, you can ignore it. The ADDSORTED command adds items in alphabetical order. It also outputs the index number of the item that was added. Type:

IGNORE ASK "LISTBOX.1 [ADDSORTED "DRAW]
IGNORE ASK "LISTBOX.1 [ADDSORTED "CLEAN]

Type the following command to change the RUN property:

PPROP "LISTBOX.1 "RUN [DO.COMMAND]

Define the following procedure:

TO DO.COMMAND
	RUN (LIST GPROP "LISTBOX.1 "TEXT)
END

The parentheses are required because LIST normally takes two inputs. When you click on one of the items in the listbox control, the DO.COMMAND will run the command.

You can change the items in a listbox control one at a time in the properties dialog. The INDEX property tells which of the items will be reported as the TEXT property of the control. When you enter a new value in the INDEX property, the TEXT property changes to show the associated value.

The other special commands for listbox and popup controls are INSERT (to add an item in the middle of the table), REPLACE (to change the TEXT property of the current item) and FIND (to locate an item whose TEXT property matches the input). When a listbox has more items than will fit in the current size, then a scrollbar is automatically displayed to let you scroll through the items.

Drag a popup control from the Toolbox and place it above the Move button. The popup control is actually a table of text items very similar to the listbox control. It works in the same way but it takes up much less space on the Graphics window - only the currently selected item is shown. When you click on a popup control, a list of items appears (or pops up) so you can make a selection. The item you select is then duplicated in the top of the control and the list disappears.

When you drag a popup control to the Graphics window, there are three items in the table, although you probably won't want to use them. An easy way to get rid of them is to ask the popup control to remove them for you. Type:

REPEAT 3 [ASK "POPUP.1 [REMOVE 0] ]

REMOVE is one of six special commands that are used by the popup and listbox controls. It takes an index number as input and removes the associated item from the table. Index number 0 is for the first item in the table. When it is removed, the other items move up - index number 1 becomes the new index number 0, and so on. The APPEND command adds a new item to the end of the table. Type:

ASK "POPUP.1 [APPEND "HOME]
Result: 0

The output of APPEND is the index number the item that was added. If you don't need to use it, you can ignore it. The ADDSORTED command adds items in alphabetical order. It also outputs the index number of the item that was added. Type:

IGNORE ASK "POPUP.1 [ADDSORTED "DRAW]
IGNORE ASK "POPUP.1 [ADDSORTED "CLEAN]

Type the following command to change the RUN property:

PPROP "POPUP.1 "RUN [POP.COMMAND]

Define the following procedure:

TO POP.COMMAND
	RUN (LIST GPROP "POPUP.1 "TEXT)
END

The parentheses are required because LIST normally takes two inputs. When you click on one of the items in the popup control, the POP.COMMAND will run the command.

You can change the items in a popup control one at a time in the properties dialog. The INDEX property tells which of the items will be reported as the TEXT property of the control. When you enter a new value in the INDEX property, the TEXT property changes to show the associated value.

The other special commands for popup and listbox controls are INSERT (to add an item in the middle of the table), REPLACE (to change the TEXT property of the current item) and FIND (to locate an item whose TEXT property matches the input). The SIZE property is for the part of the popup control that is always visible. The table's display size is automatically adjusted as more items are added. When a popup has more items than will fit in the maximum table size, then a scrollbar is automatically displayed to let you scroll through the items in the list.

Controls for STATES

Restart Logo and then load the STATES workspace file. Define the SETUP procedure to add four controls to the Graphics window. The popup control will have a table of all of the state abbreviations - and, you won't have to type them in! Since each state has a CAPITAL property, the GLIST command will find them all. The FOREACH command will add each abbreviation to the popup control by asking it to add each abbreviation in alphabetical order. The three statictext controls will display the full name, nickname and the baseball teams for the state that appears in the popup control. The SETUP procedure also loads the map and uses the turtle to fill in the outer area with the SILVER color.

When you select a state abbreviation in the popup control, the UPDATE.INFO procedure is run that sets the TEXT property of the three statictext controls. Define the UPDATE.INFO procedure:

The CURRENT.STATE procedure outputs the abbreviation currently displayed in the popup control. Its definition is:

SETUP.lgo
TO SETUP
	DECLARE "POPUP "SELECT.STATE
	PPROP "SELECT.STATE "POSITION [-250 -130]
	PPROP "SELECT.STATE "RUN [UPDATE.INFO]
	FOREACH GLIST "CAPITAL [IGNORE ASK "SELECT.STATE [ADDSORTED "?]]

	DECLARE "STATICTEXT "STATE.NAME
	PPROP "STATE.NAME "SIZE [150 16]
	PPROP "STATE.NAME "POSITION [-125 -130]

	DECLARE "STATICTEXT "STATE.NICKNAME
	PPROP "STATE.NICKNAME "SIZE [150 16]
	PPROP "STATE.NICKNAME "POSITION [30 -130]

	DECLARE "STATICTEXT "BASEBALL.TEAMS
	PPROP "BASEBALL.TEAMS "SIZE [150 16]
	PPROP "BASEBALL.TEAMS "POSITION [185 -130]

	UPDATE.INFO
END

TO UPDATE.INFO
	PPROP "STATE.NAME "TEXT FULLNAME? CURRENT.STATE
	PPROP "STATE.NICKNAME "TEXT NICKNAME? CURRENT.STATE
	PPROP "BASEBALL.TEAMS "TEXT BASEBALL? CURRENT.STATE
END

TO CURRENT.STATE
	GPROP "SELECT.STATE "TEXT
END 

Save your workspace and then type:

SETUP

You can add more controls for other information. Add other statictext controls for labels. Using the XY property suggested earlier, you could use the turtle to fill in selected state with a color; that could serve as a visual reminder that you already looked at that state's information.

Controls for SIMON

Restart Logo and then load the SIMON workspace file. With two radiobutton controls, you can easily switch between turtle shapes and the proper shapes. Define the SETUP procedure to create the radiobutton controls. The STATE property of the TURTLE.SHAPES control has been set to TRUE so it looks like it's already been selected.

Each radiobutton control runs its own procedure to turn off the other control and then change the shapes of the turtles. Define USE.TURTLES and USE.PROPER.

The SIMON procedure is shown below - all you should have to do is add the call to SETUP before the first guess is made.

SIMON.lgo
TO SETUP
	DECLARE "RADIOBUTTON "TURTLE.SHAPES
	PPROP "TURTLE.SHAPES "TEXT "|Turtle shapes|
	PPROP "TURTLE.SHAPES "RUN [USE.TURTLES]
	PPROP "TURTLE.SHAPES "POSITION [210 10]
	PPROP "TURTLE.SHAPES "SIZE [90 18]
	PPROP "TURTLE.SHAPES "STATE TRUE
	
	DECLARE "RADIOBUTTON "PROPER.SHAPES
	PPROP "PROPER.SHAPES "TEXT "|Proper shapes|
	PPROP "PROPER.SHAPES "RUN [USE.PROPER]
	PPROP "PROPER.SHAPES "POSITION [210 -10]
	PPROP "PROPER.SHAPES "SIZE [90 18]
END

TO USE.TURTLES
	PPROP "PROPER.SHAPES "STATE "FALSE
	ASK [1 2 3 4] [(SETSHAPE)]
END

TO USE.PROPER
	PPROP "TURTLE.SHAPES "STATE "FALSE
	ASK 1 [SETSHAPE "|~HOME/TOOLBOX/BIRDS/SPARROW2|]
	ASK 2 [SETSHAPE "|~HOME/TOOLBOX/ANIMALS/BEE|]
	ASK 3 [SETSHAPE "|~HOME/TOOLBOX/OTHER PICTURES/TELEPHONE|]
	ASK 4 [SETSHAPE "|~HOME/TOOLBOX/VEHICLES/BEETLE|]
END

TO SIMON
	CLEARSCREEN SETTURTLES 5 SETTSIZE 2
	TELLALL 1 4 PENUP LEFT 45
	EACH [RIGHT WHO * 90 FORWARD 100 SETHEADING 0]
	SETTSIZE 5 SHOWTURTLE PPROP 0 "RUN [GUESS]
	PPROP 1 "RUN [JOB 1] PPROP 2 "RUN [JOB 2]
	PPROP 3 "RUN [JOB 3] PPROP 4 "RUN [JOB 4]
	SETUP 
	GUESS
END

Controls for PUZZLE

The illustration for the puzzle game looks like it might be terribly complicated, but it's not really very complicated at all. An extra Graphics window is used to separate the controls from the actual puzzle. This is done for two reasons: (1) the controls could get in the way of the puzzle pieces, and (2) the CLEARSCREEN command would erase all of the controls from the current window.

There is only one change needed to the original MAKE.PUZZLE procedure. You have to include the line SETACTIVEWINDOW “GRAPHICS as the first line. All of the activity in MAKE.PUZZLE occurs in the window titled Puzzle which is really the normal Graphics window.

PUZZLE.lgo
; The SETUP procedure calls on other supporting procedures to do 
; most of the work of setting up the windows and controls. The 
; SETACTIVEWINDOW command is like a TELL command for windows - 
; the following activity takes place in the current window (except 
; SETBG, which applies to all windows at the same time). 

TO SETUP
    DO.WINDOWS
    SETACTIVEWINDOW "GRAPHICS.1
    CREATE.INFO
    CREATE.PICTURES
    CREATE.PIECES
    CREATE.BUTTON
    PPROP "PIECE.SLIDER "VALUE 8
    PPROP "PIECES "TEXT 8
    PPROP "PICTURES "INDEX 0
    PPROP "LISTENER "VISIBLE "FALSE
END

; The DO.WINDOWS procedure creates a new Graphics window, 
; arranges the windows and gives each one a new title.

TO DO.WINDOWS
  	IGNORE NEW "GRAPHICS
  	SETBG "SILVER
  	PPROP "GRAPHICS.1 "POSITION [0 0]
  	PPROP "GRAPHICS.1 "SIZE [196 483]
  	PPROP "GRAPHICS.1 "TITLE "|Puzzle Controls|
  	PPROP "GRAPHICS "POSITION [196 0]
  	PPROP "GRAPHICS "SIZE [434 483]
  	PPROP "GRAPHICS "TITLE "|Puzzle|
END

; The CREATE.INFO procedure uses a statictext control as an 
; information display. Make sure you enter the information in the 
; TEXT property as one long line.

TO CREATE.INFO
  	DECLARE "STATICTEXT "INFO
  	PPROP "INFO "POSITION [0 140]
  	PPROP "INFO "SIZE [150 60]
  	PPROP "INFO "TEXT (WORD "|Select a picture for your puzzle. |
  		"|Select the number of pieces. Then click PLAY and |
  		"|try to put it back together again.|)
END

; The CREATE.PICTURES procedure uses a listbox control to display 
; the choices of pictures from the Animals folder. You can add more if 
; you want.

TO CREATE.PICTURES
  	DECLARE "LISTBOX "PICTURES
  	PPROP "PICTURES "POSITION [0 20]
  	IGNORE ASK "PICTURES [ADDSORTED "|Elephant|]
  	IGNORE ASK "PICTURES [ADDSORTED "|Rhino|]
  	IGNORE ASK "PICTURES [ADDSORTED "|Zebra|]
  	IGNORE ASK "PICTURES [ADDSORTED "|Cat|]
  	IGNORE ASK "PICTURES [ADDSORTED "|Giraffe|]
  	IGNORE ASK "PICTURES [ADDSORTED "|Peacock|]
END

; The CREATE.BUTTON procedure uses a button control
; for starting the game.

TO CREATE.BUTTON
  	DECLARE "BUTTON "PLAY.BUTTON
  	PPROP "PLAY.BUTTON "POSITION [0 -140]
  	PPROP "PLAY.BUTTON "TEXT "PLAY
  	PPROP "PLAY.BUTTON "RUN [
  		MAKE.PUZZLE "ANIMALS GET.PICTURE GET.PIECES]
END

; The CREATE.PIECES procedure uses a scrollbar to set the number of 
; puzzle pieces. You can adjust the minimum, maximum and increments to 
; suit yourself. The statictext control is used to show the number of 
; pieces selected.

TO CREATE.PIECES
  	DECLARE "SCROLLBAR "PIECE.SLIDER
  	PPROP "PIECE.SLIDER "POSITION [0 -80]
  	PPROP "PIECE.SLIDER "MINIMUM 3
  	PPROP "PIECE.SLIDER "MAXIMUM 20
  	PPROP "PIECE.SLIDER "LARGEINC 2
  	PPROP "PIECE.SLIDER "TOOLTIP "|Puzzle pieces|
  	PPROP "PIECE.SLIDER "RUN [CHANGE.PIECES]
  	DECLARE "STATICTEXT "PIECES
  	PPROP "PIECES "POSITION [0 -100]
  	PPROP "PIECES "SIZE [16 16]
END

; The following supporting procedures are used to get the values of 
; controls and to display the number of pieces.

TO GET.PICTURE
  	OUTPUT GPROP "PICTURES "TEXT
END
  
TO GET.PIECES
  	OUTPUT GPROP "PIECES "TEXT
END
  
TO CHANGE.PIECES
  	PPROP "PIECES "TEXT ROUND CURRENT.PIECES
END
  
TO CURRENT.PIECES
  	GPROP "PIECE.SLIDER "VALUE
END

; These are the procedures from chapter 7: Bitmaps and Animation

TO MAKE.PUZZLE FOLDER PICTURE PIECES
	; you need to switch the active window
	SETACTIVEWINDOW "GRAPHICS
	SETTURTLES 1 TELL 0 CS HT SETH 90 PU SETBG "SILVER
	IGNORE LOADSNAP (WORD "|~HOME/TOOLBOX/| FOLDER "|/| PICTURE)
	ASK "BITMAP.1 [HT]
	SETXY GPROP "BITMAP.1 "SIZE
	SETX -1 * XCOR SETY -1 * YCOR
	(STAMP "BITMAP.1)
	FOR "I 1 PIECES [
		IGNORE SNAP SLICE.WIDTH PIECES SLICE.HEIGHT
		FD SLICE.WIDTH PIECES
	]
	CLEAN ERASE "BITMAP.1
	TELL EVERY "BITMAP
	EACH [PPROP WHO "WINDOW "GRAPHICS]
	EACH [SETH 90 FD RANDOM 150]
END

TO SLICE.WIDTH PIRCES
	OUTPUT (FIRST GPROP "BITMAP.1 "SIZE) / PIECES
END

TO SLICE.HEIGHT
	OUTPUT LAST GPROP "BITMAP.1 "SIZE
END

It may take a bit of time to get the hang of using Graphical controls, but the effort is well worth it. Trying to decide where to place them and getting them lined up properly is the most time-consuming part of it. It helps to play around interactively. Drag a control to where you want it to appear, then edit the properties to get the position coordinate. Using an extra Graphics window can be a big help.

Save your workspace. Next time you load it, just type SETUP to get it going. You could add other controls to select different folders.

logo/tutorial/chapter8.txt · Last modified: 2018/08/27 03:39 (external edit)