NS BASIC Tech Note December 18, 1996
31. Widgets By Hand, a detailed example
--------------------------------------------------------------------------
This technote describes using widgets without the Visual Designer or the
WIDGETDEF Statement. See Chapter 4 in the Handbook for an example of using
the Visual Designer to build Newton interfaces.
A widget is a Newton user interface element. In the NewtonScript language,
widgets are called protos and view templates. You can create programs that
use many of the visual elements found in Newton applications. Refer to the
Reference section under WINDOW for a complete list of widgets.
When you want to create an application that uses widgets, you combine
windows and widgets to create a single screen that the user interacts
with. This screen may consists of many widgets. Once the widgets are
displayed, the user can interact with the screen using pen taps,
hand-written input, and the keyboard. Your screen must be designed so that
the user can indicate when they are finished entering information. A
window that looks like a Newton button can be used. You can create a main
window for your application using the APP widget. This widget includes a
standard close box. You can add one or more additional windows that look
like Newton buttons, such as an "OK" button. These windows will use a
GOTO field in their windowSpec to allow your program to process the user
entry in the form.
The following sample program creates a simple database with a form for
user entry. It supports searching for records and adding new records. It
uses several widgets for the form.
The three sections of the program you should examine are the creation of
the widgets (lines 130-330), the extraction of the user entered values
from the widgets (lines 500-510), and the displaying of new values in
widgets (lines 430-470).
Note: Never use the same windowSpec variable in multiple WINDOW Statements
without first assigning a new frame value to the variable. This is done in
the example below with the spec variable. Each time this variable is used
in a WINDOW Statement, it is initialized with a new frame containing the
desired fields for the window.
10 REM WIDGET Example
20 OPEN example, "ExampleFile", Name
30 IF FSTAT <> 0 THEN CREATE Â
example, "ExampleFile", Name
70 spec := {GOTO: 'appDone, Â
title: "Sample App"}
80 WINDOW MainWindow, spec, "APP"
110 SHOW MainWindow
130 REM create and display blank form
150 spec := {GOTO: 360, text: "Search", viewBounds: SETBOUNDS(6, 280,
66, 294), widgetType:"TEXTBUTTON"}
160 WINDOW SearchBtn, spec, "TEXTBUTTON"
170 spec := {GOTO: 490, text: "Save", viewBounds: SETBOUNDS(70, 280, 130,
294), widgetType:"TEXTBUTTON"}
180 WINDOW SaveBtn, spec, "TEXTBUTTON"
190 spec := {GOTO: 540, text: "New", viewBounds: SETBOUNDS(134, 280, 191,
294), widgetType:"TEXTBUTTON"}
200 WINDOW NewBtn, spec, "TEXTBUTTON"
210 NameSpec := {label: "Name:", viewBounds: SETBOUNDS(9, 30, 230, 64),
viewFlags: VCLICKABLE}
220 WINDOW Name, NameSpec, "LABELINPUT"
230 RankLabelSpec := {text:"RANK\n1 2 3 4 5 6 7 8 9", viewJustify:3,
viewFormat: vfPen+vfFrameWhite, viewBounds: SETBOUNDS(21, 65, 230, 109),
viewFlags: VCLICKABLE}
240 WINDOW RankLabel, RankLabelSpec, "PARAGRAPH"
250 RankSpec := {viewValue:0, viewBounds: SETBOUNDS(21, 110, 230, 119),
viewFlags: VCLICKABLE}
260 WINDOW Rank, RankSpec, "SLIDER"
270 ContactSpec := {label: "Contact:", labelCommands: ["Now", "Soon",
"Someday", "Never"], viewBounds: SETBOUNDS(9, 120, 230, 144), viewFlags:
VCLICKABLE}
280 WINDOW Contact, ContactSpec, "LABELINPUT"
290 CalledSpec := {text: "Called", viewBounds: SETBOUNDS(21, 145, 110,
179), viewFlags: VCLICKABLE}
300 WINDOW Called, CalledSpec, "CHECKBOX"
310 NotesSpec := {boxTitle:"Notes", text: "", viewBounds: SETBOUNDS(21,
180, 230, 254), viewFlags: VCLICKABLE}
320 WINDOW Notes, NotesSpec, "SCROLLER"
330 SHOW SearchBtn, SaveBtn, NewBtn, Name, RankLabel, Rank, Contact,
Called, Notes
340 waitLoop: Wait 1000
350 GOTO waitLoop
360 REM user taps Search
370 searchKey = NameSpec.entryLine.text
380 GET example, editRec, searchKey
390 IF FSTAT <> 1 THEN GOTO 0420
400 BEEP 7
410 GOTO 340
420 REM found something!
430 SETVALUE(NameSpec.entryLine, 'text, "" & editRec.name)
440 SETVALUE(RankSpec, 'viewValue, editRec.rank)
450 SETVALUE(ContactSpec.entryLine, 'text, "" & editRec.contact)
460 IF CalledSpec.viewValue <> editRec.called THEN
U.CalledSpec:TOGGLECHECK()
470 SETVALUE(NotesSpec.notes, 'text, "" & editRec.notes)
480 GOTO 340
490 REM user taps Save
500 newRecord = {name:NameSpec.entryLine.text,Â
rank:RankSpec.viewValue, contact:Â
ContactSpec.entryLine.text, Â
called: CalledSpec.viewValue, Â
notes: NotesSpec.notes.text}
510 PUT example, newRecord
520 IF FSTAT <> 0 THEN BEEP 7 ELSE BEEP 4
530 GOTO 0340
540 REM user taps New
550 SETVALUE(NameSpec.entryLine, 'text, "")
560 SETVALUE(RankSpec, 'viewValue, 0)
570 SETVALUE(ContactSpec.entryLine, 'text, "")
580 IF CalledSpec.viewValue THEN x = U.CalledSpec:TOGGLECHECK()
590 SETVALUE(NotesSpec.notes, 'text, "")
600 GOTO 340
610 appDone: REM user taps close box
620 HIDE
630 END