Basic graphical window operations Tutorial
1.1 Radio Buttons
So far, you've learned how to ask the user to enter information using INPUT FIELDS. But what if you only want to know a simple yes or no answer? Instead of typing Y or N or any other option, you can simply provide a radio button or checkbox instead.
Enter the following code:
10 LET Y$=”Yes”: let N$=”No” 15 RINPUT FIELDS “2,5,radio 4,2,8;3,5,radio 3,2,9”:Y$,N$
and run it. You have a set of radio buttons!
Next edit line 10 to include a carrot (^) before Yes:
10 LET Y$=”^Yes”: let N$=”No”
When you run it this time, you should notice a small change.
This time, “Yes” is auto-selected. (Thanks to the carrot symbol!)
It will still let you change it to “No,” of course.
Next, add the following two lines:
20 IF Y$(1:1)=”^” THEN print y$, else print n$ 25 print FKEY
Then run the program, and make a selection.
The carrot also identifies which radio button was selected. Keep this notation in mind when writing user selections to a file. But what is the FKEY? It should be 8 or 9, depending on whether “Yes” or “No” was selected. Let's take a closer look at the syntax of our example:
RINPUT FIELDS “2,5,radio 4,2,8;3,5,radio 3,2,9”:Y$,N$
RINPUT FIELDS means that the program prints the radio button and a label and then waits for an input or change. Using INPUT FIELDS will simply display the radio buttons without their captions. Using PRINT FIELDS will only print the button and label but not wait for input, which is useful for displaying pre-recorded results. Typically, a program would require RINPUT for data entry and PRINT for reporting. INPUT FIELDS is useful if the caption is printed by another program line, and allows the button to appear to the right of the words.
Continuing with the above syntax, 2 and 5 denote the rows and columns where the radio button will appear, RADIO makes it a radio button. The number immediately following RADIO says how many columns the caption will be (allow an extra column for the carrot). Then comes the group number (here we have group 2) and last the FKEY value assigned when its selected.
It's important to remember that radio buttons are grouped, which means that selecting one will deselect the others in the group, so only one FKEY value will be valid at a time. To select multiple values in a group, either make each button its own group, or use check boxes.
Let's review the syntax once more with all possible parameters:
INPUT/RINPUT/PRINT FIELDS row, col, RADIO cols, group attribute, FKEY, NOWAIT: “^caption”
“Row” and “col” tell BR where on the screen to begin the radio button label and “cols” says how many columns wide the caption will be.
“Group” refers to which group the button will be in (assuming you want more than one to select) and “attribute” is any attribute you'd like to add.
The FKEY is specified, an FKEY interrupt is generated when the item is clicked ON or OFF.
NOWAIT denotes the G attribute, which returns control immediately to the program.
The optional carrot (^) at the beginning of the caption indicates a preselected setting but is not displayed. The caption must be placed in a variable for either INPUT or RINPUT FIELDS statements, as in the example used for this section. The parameters are repeated after a semi-colon for multiple radio buttons in a group.
We are going to create a short program that records order information for a company. Write the portion of the code that asks the user about whether they want overnight or regular shipping. It should look something like this, but feel free to customize it a little. Save it under the name Chapter1.br:
Reminder: The use of FKEY saves a certain value in FKEY, so that the user's selection can be recorded to a file.
If you need help, a sample program is available on the solutions page.
Like radio buttons, checkboxes provide another way to get simple input from the user. However, checkboxes are not grouped, so they allow more than one selection. The user can select one, several, or none of the available choices. Enter the following lines and run them:
00030 let H$=”Happy?” 00040 RINPUT FIELDS “5,5,CHECK 10,,8”: H$
You can select the checkbox.
Checkbox syntax is very similar to radio button syntax, but without the group number:
INPUT/RINPUT/PRINT FIELDS row, col, CHECK cols, attribute, FKEY, NOWAIT: “^caption”
Notice that if you skip the optional parameters, you will still have to include a comma in its place.
Let's go ahead and add another checkbox option to our example. Modify your code to look like this:
00030 let H$="Happy?": let M$="Healthy?" 00040 RINPUT FIELDS "5,5,CHECK 10,,8;6,5,CHECK 10,,8": H$,M$
Could you check both boxes? Since the user may select more than one or none at all, the program must changed to wait for all possible input to be completed before ending. One easy way to do this is with a DO LOOP and the FKEY values. Update your example to look like this:
00030 let H$="Happy?": let M$="Healthy?" 00040 PRINT FIELDS "8,1,C 20": "Press Esc to quit" 00050 DO 00060 RINPUT FIELDS "5,5,CHECK 10,,8;6,5,CHECK 10,,8": H$,M$ 00070 LOOP while fkey~=99
Once the user has selected their checkboxes, or decided to select neither, ESC will end the program.
Add to your CHAPTER1.br program by allowing the user to choose from three different items to order. Refer to the solutions page if you need help.
Now that the user has input all the data into your CHAPTER1 program, instead of hitting the escape key, wouldn't it be great to have an exit button? Or a button to complete other actions like print a mailing label or prepare an invoice? Since version 4.15, BR can create buttons on the screen.
Take a look at this example:
00500 print fields "23,30,CC 8,,B99" : "Done"
Buttons are created using PRINT FIELDS, with the starting row and column, attributes (Characters and Centered in this case), button size (in columns), the B (for button!) and the FKEY value, which is set to 99 in this case. After the colon is the caption. If you run this example, it will print the button beautifully but do nothing.
That's because buttons depend on the program waiting for the user to click it, which sets the Fkey value, and so triggers the desired action. Therefore, the program must be waiting for something else to happened as it waits for that Fkey to be set (by clicking it). It could wait for a checkbox or radio button selection, input information, or even just a dummy input. For this reason, buttons pair well with input forms.
Here's an example:
00490 dim box$(3) 00500 print fields "23,30,CC 8,,B99" : "Done" 00510 data "Item 1","Item 2","Item 3" 00520 read mat Box$ 00530 do 00540 rinput fields "22,14,CHECK 8,,10;23,14,CHECK 8,,11;24,14,CHECK 8,,12": Box$(1),Box$(2),Box$(3) 00550 print fields "24,1,N 2": Fkey 00560 loop While Fkey~=99
Line 500 creates the button on the screen with print fields “row,col, attributes length, , B99”, where the B stands for button and the 99 sets the FKEY value. After the colon, the “Done” will be the label on the button. This example lets the user choose from several checkboxes, and then click the button, which ends the LOOP and in this case the program. In other programs, the FKEY could be set to run other activities as well.
A. Add an exit button to the sample program that we've been working on in this chapter. See the solutions if necessary.
B. For use in the next sections, also add input fields for customer name and address, then write all the information into a file called ORDERS.INT. Run the program several times so that you have quite a few entries in the file to work with (this should all be review from the first tutorial). Once again see the solutions page if you need help.
Lists are table-like structures that allow the user to select a row, column, or cell. Grids are the same but also allow for input (and are described in section 1.5). They are made of rows and columns. Outputting to lists is done with Print Fields and inputting from them is done with Input Fields. Information in lists can be sorted alphabetically by clicking on a column heading, which affects the appearance on the screen but does not change the order of the original file with the information.
There are three steps for creating lists or grids: 1. Create a header 2. Populate the list or grid 3. Allow user activity
1. The header
When creating a list or grid, it's recommended that you create a header row with titles for each column, as seen in the example. Headers are created with the following syntax, using Print Fields:
00010 print fields "2,2,list 10/80,headers": (MAT HEADINGS$,MAT WIDTHS,MAT FORMS$)
The parameters are:
print or input fields “row,col, LIST rows/size,HEADERS”:(input or output list)
row and col specify where the list begins, LIST means we're creating a list. rows/size specify how many rows are included and how wide the whole list will be in columns. If your list has more rows than are described here, BR will automatically add a scroll bar to view them. HEADERS means that this is the headers row.
The HEADINGS$, WIDTHS, and FORMS$ arrays contain the information needed for the header row. HEADINGS$ might include things such as: “Name”, “Address”, and “Order #”; WIDTHS gives the number of columns of the screen that each column should take up: 10, 10, 6; and FORMS$ tells whether each is a string or numeric variable, its size, and may include attributes such as alignment: “cc 15”, “cc 15”, “n 6”.
Let's work through an example together:
First, set up the header:
00002 dim headings$(3),widths(3),forms$(3) 00003 data "Item","Color","ID number" 00004 read mat headings$ 00005 data 12,12,12 00006 read mat widths 00007 data "c 12","c 12","n 5" 00008 read mat forms$ 00009 print fields "2,2,list 10/36,headers": (Mat Headings$,Mat Widths,Mat Forms$)
and run this! You'll see the header printed at the top of your screen.
2. Populating the list
To populate the list, the syntax looks like this:
print fields "2,2,list 10/80,=r": (mat FirstName$, mat LastName$,mat Address$,mat City$,mat state$,mat zipcodes$,mat shipmethod$,mat item1,mat item2,mat item3)
Notice how the “2,2,list 10/80, part is the same as the headers line example. This tells BR that you are filling in the same list. The equal sign is a primary flag.
In order to fill a list there are three possible primary flags:
|=||Replace any previous data|
|+||Add to any previously populated data (this allows loading in chunks)|
|-||Insert data ahead of previously populated data (4.16+)|
And the R is a secondary flag, for which there are four options:
|R||Load one row at a time (the default)|
|C||Load one column at a time - This is for loading multiple columns of the same data type|
|L||Provide the FKEY (see INPUT below) or Enter interrupt if the user presses up arrow or page up in the first field, or down arrow or page down in the last field. Note that this is not specified in the individual field leading attributes.|
|S||Single click to activate an Enter or FKEY event (otherwise a double click is required) (4.17+)|
The arrays in parenthesis after the colon contain the information which will be displayed in your list.
In our working example, we'll use our list data and mat Item$, mat Color$, mat idnum to populate the list, as follows:
00011 ! .! provide sample info for list 00012 dim item$(5),color$(5),idnum(5) 00013 data "Door","Frame","Rim","Handle","Padding","Black","Grey","Red","Lime","Sky Blue",1234,5556,7889,5378,1596 00014 read mat item$: read mat color$: read mat idnum 00015 ! 00016 ! .! populate list 00017 print fields "2,2,list 10/36,+r": (Mat Item$, Mat Color$, Mat Idnum)
3. Allowing User Activity
With lists, the only possible activity is selection. But there are several ways to select things, including by row, column, or cells. This could be useful for your computer to record selections to a file or for the user to choose something from a large list. Input Fields is used for this task, as in the following example, which will record which row is selected:
00018 input fields "2,2,list 10/36,rowsub,selone": selection
Go ahead and add this line to your sample program.
The first part remains the same again, but here we have the parameters ROWSUB and SELONE. ROWSUB records the row subscript of the selected row, and the SELONE specifies that only one row can be selected. Other parameters for the first include: RowCnt, Row, Colcnt, and Sort_Order for the first parameter, and for the second: Sel, All, Cur, Range, and Cell_Range. Refer to the wiki for details on each.
There are two optional parameters not shown here: Fkey and Nowait. FKEY means that an FKEY event should be triggered when a selection is made by double clicking or pressing the Enter key in navigation mode. Nowait simply means that it does not wait for user input.
If you run your program now, it will let you select a row (press enter to exit for now).
But what should we do with that selection?
One option would be to display which row the user selected. Add the following line to your program:
00019 print selection
Now when you exit the list view, it will display the subscript of the row you selected. This information could be saved or used to reference a line for editing or printing in another program.
Earlier in this chapter, we created a data file called ORDERS.int to record information about our customers and their orders. Run this program several times so that you have some records in your file to work with.
Now, write a new program that accesses that file and prints all the information to a list. Allow the user to select a row.
You will have to follow the steps above, and add lines for dealing with the data file:
- Print the headers.
- Open the file.
- Read the data file into arrays and use them to populate the list.
- Allow users to select a row and print the subscript of that row.
- Provide an exit button when complete.
Refer to Sample program: Samplist.br in the solutions if you get stuck.
Like lists, GRIDS are made of rows and columns and are created using INPUT FIELDS and PRINT FIELDS. However, with grids the user can change information within the cells. This is handy for updating files.
Just like lists, the data in grids can be sorted according to the column header that the user clicks on. And once again this changes the data's appearance but does not change its form in the file.
1. Grids also have a header row defined by headings, widths, and forms:
00250 PRINT FIELDS "2,2,GRID 10/36,headers": (Mat Headings$,Mat Widths,Mat Forms$)
2. Then information must be populated in the grid:
03020 PRINT FIELDS "2,2,GRID 10/36, =": (Mat Item$, Mat Color$, Mat Idnum)
Grids use the same primary and secondary flags as lists for population.
3. When handling user activities, grids can use the same read and selection types as lists, as seen in the charts above. Grids also have extra options that cannot be used in lists:
Read types for grids only:
|Cnt||Specify the number of cells specified (see selection types).|
|Sub||Read the Cell Subscript Values.|
|Cell||Read each cell specified.|
There is one Selection Type valid for Grids only, which allows the user to edit values in the grid:
|Chg||All items changed since the last '=' populate or the last CHG retrieval of cell/row contents.|
Reopen the program you've been working on in the chapter exercises (using the information from ORDERS.INT), save it under the name GRID1 and change all instances of LIST to GRID. (There are three in our program).
Then run the program. What differences do you see?
Now you can select one cell at a time instead of one row at a time, and make changes! Go ahead and try it!
Run it again.
Have your changes been saved? (No!?) Next we'll need to change the program to record what you've done. You will need to use the CHG selection type, record the rows with changes into a new array, and then rewrite the rows that were changed into the file. Try to do this alone without looking ahead first.
For help, see the program 1.5 part one, on the Solutions page.
Go ahead and run the sample program to try it now! Need more evidence? If you re-run the original program Samplist, will you find your new changes available for selection? (Yes!)
Next, what if you want to add an entire new entry? Remember the primary flags above? Edit your program to add a new record. And then to save the new entry in the file. See part 2 on the solutions page for help.