A First Look at Graphical User Interfaces

external ~<#65669#>The section's examples and exercises require the teachpack <#30283#>gui.ss<#30283#>, which provides some basic operations for building and managing GUI items. Like <#30284#>draw.ss<#30284#>, this teachpack simplifies this process but also gives much less control over the details of the process than the actual DrScheme toolbox.<#65669#> Functions as first-class values play a central role in the design of graphical user interfaces. The term ``interface'' refers to the boundary between the program and a user. As long as we are the only users, we can apply functions to data in DrScheme's <#30285#>Interaction<#30285#> window. If we want others to use our programs though, we must provide a way to interact with the program that does not require any programming knowledge. The interaction between a program and a casual user is the <#65670#><#30286#>USER INTERFACE<#30286#><#65670#>. A <#65671#><#30287#>GRAPHICAL USER INTERFACE<#30287#><#65671#> (GUI) is the most convenient interface for casual users. A GUI is a window that contains GUI items. Some of these items permit users to enter text; others are included so that users can apply a specific function; and yet others exist to display a function's results. Examples include <#30288#>buttons<#30288#>, which the user can click with the mouse and which trigger a function application; <#30289#>choice menus<#30289#>, from which the user can choose one of a collection of values; <#30290#>text fields<#30290#>, into which the user can type arbitrary text; and <#30291#>message fields<#30291#>, into which a program can draw text.
rawhtml39 <#30292#>Figure: A simple GUI for looking up phone number<#30292#>
Take a look at the simple GUI in figure~#figlookupgui#30294>. The left-most picture shows its initial state. In that state, the GUI contains a text field labeled ``Name'' and a message field labeled ``Number'', plus a ``LookUp'' button. In the second picture, the user has entered the name ``Sean'' but hasn't yet clicked the ``LookUp'' button. Finally, the right-most picture shows how the GUI displays the phone number of ``Sean'' after the user clicks the ``LookUp'' button. The core of the program is a function that looks up a phone number for a name in a list. We wrote several versions of this function in part~#partstructural#30296> but always used it with DrScheme's <#30297#>Interaction<#30297#> window. Using the GUI of figure~#figlookupgui#30298>, people who know nothing about Scheme can now use our function, too. To build a graphical user interface, we construct structures that correspond to the GUI items and hand them over to a GUI manager. The latter builds the visible window from these items. Some of the structures' fields describe the visual properties of the GUI's elements, such as the label of a button, the initial content of a message field, or the available choices on a menu. Other fields stand for functions. They are called <#30300#>call-back functions<#30300#> because the GUI manager calls---or applies---these functions when the user manipulates the corresponding GUI element. Upon application, a call-back function obtains strings and (natural) numbers from the elements of the GUI and then applies the function proper. This last step computes answers, which the call-back function can place into GUI elements just like graphics functions draw shapes onto a canvas.

#picture30302#

<#30338#>Figure: The model-view arrangement<#30338#>


The ideal program consists of two completely separate components: the <#65696#><#30340#>MODEL<#30340#><#65696#>, which is the kind of program we are learning to design, and a <#65697#><#30341#>VIEW<#30341#><#65697#>, which is the GUI program that manages the display of information and the user's mouse and keyboard manipulations. The bridge between the two is the <#65698#><#30342#>CONTROL<#30342#><#65698#> expression. Figure~#figmvc#30343> graphically illustrates the organization, known as the <#65699#><#30344#>MODEL-VIEW-CONTROL<#30344#><#65699#> architecture. The lowest arrow indicates how a program makes up a button along with a call-back function. The left-to-right arrow depicts the mouse-click event and how it triggers an application of the call-back function. It, in turn, uses other GUI functions to obtain obtain user input before it applies a core function or to display results of the core function. The separation of the program into two parts means that the definitions for the model contain no references to the view, and that the definitions for the view contain no references to the data or the functionality of the model. The organization principle evolved over two decades from many good and bad experiences. It has the advantage that, with an adaptation of just the bridge expression, we can use one and the same program with different GUIs and <#30345#>vice versa<#30345#>. Furthermore, the construction of views requires different tools than the construction of models. Constructing views is a labor-intensive effort and graphical design, but fortunately, it is often possible to generate large portions automatically. The construction of models, in contrast, will always demand a serious program design effort.
A <#65700#><#30347#>gui-item<#30347#><#65700#> is either
  1. <#65701#><#30349#>(make-button<#30349#>\ <#30350#>string<#30350#>\ <#30351#>(X<#30351#>\ <#30352#><#30352#><#30353#>-;SPMgt;<#30353#><#30354#><#30354#>\ <#30355#>true))<#30355#><#65701#>
  2. <#65702#><#30356#>(make-text<#30356#>\ <#30357#>string)<#30357#><#65702#>
  3. <#65703#><#30358#>(make-choices<#30358#>\ <#30359#>(listof<#30359#>\ <#30360#>string))<#30360#><#65703#> or
  4. <#65704#><#30361#>(make-message<#30361#>\ <#30362#>string)<#30362#><#65704#>.
<#71390#>;; <#65705#><#30369#>create-window<#30369#> <#30370#>:<#30370#> <#30371#>(listof<#30371#> <#30372#>(listof<#30372#> <#30373#>gui-item))<#30373#> <#30374#><#30374#><#30375#>-;SPMgt;<#30375#><#30376#><#30376#> <#30377#>true<#30377#><#65705#> <#71390#>
<#30378#>;; to add gui-items to the window and to show the window<#30378#> 
<#30379#>;; each list of gui-items defines one row of gui items in the window<#30379#> 
<#71391#>;; <#65706#><#30380#>hide-window<#30380#> <#30381#>:<#30381#> <#30382#><#30382#><#30383#>-;SPMgt;<#30383#><#30384#><#30384#> <#30385#>true<#30385#><#65706#> <#71391#> 
<#30386#>;; to hide the window<#30386#> 
<#71392#>;; <#65707#><#30387#>make-button<#30387#> <#30388#>:<#30388#> <#30389#>string<#30389#> <#30390#>(event%<#30390#> <#30391#><#30391#><#30392#>-;SPMgt;<#30392#><#30393#><#30393#> <#30394#>true)<#30394#> <#30395#><#30395#><#30396#>-;SPMgt;<#30396#><#30397#><#30397#> <#30398#>gui-item<#30398#><#65707#> <#71392#> 
<#30399#>;; to create a button with label and call-back function <#30399#> 
<#71393#>;; <#65708#><#30400#>make-message<#30400#> <#30401#>:<#30401#> <#30402#>string<#30402#> <#30403#><#30403#><#30404#>-;SPMgt;<#30404#><#30405#><#30405#> <#30406#>gui-item<#30406#><#65708#> <#71393#> 
<#30407#>;; to create an item that displays a message<#30407#> 
<#71394#>;; <#65709#><#30408#>draw-message<#30408#> <#30409#>:<#30409#> <#30410#>gui-item[<#30410#><#30411#>message%<#30411#><#30412#>]<#30412#> <#30413#><#30413#><#30414#>-;SPMgt;<#30414#><#30415#><#30415#> <#30416#>true<#30416#><#65709#> <#71394#> 
<#30417#>;; to display a message in a message item <#30417#> 
<#30418#>;; it erases the current message <#30418#> 
<#71395#>;; <#65710#><#30419#>make-text<#30419#> <#30420#>:<#30420#> <#30421#>string<#30421#> <#30422#><#30422#><#30423#>-;SPMgt;<#30423#><#30424#><#30424#> <#30425#>gui-item<#30425#><#65710#> <#71395#> 
<#30426#>;; to create an item (with label) that allows users to enter text<#30426#> 
<#71396#>;; <#65711#><#30427#>get-text<#30427#> <#30428#>:<#30428#> <#30429#>gui-item[<#30429#><#30430#>text%<#30430#><#30431#>]<#30431#> <#30432#><#30432#><#30433#>-;SPMgt;<#30433#><#30434#><#30434#> <#30435#>string<#30435#><#65711#> <#71396#> 
<#30436#>;; to determine the contents of a text field <#30436#> 
<#71397#>;; <#65712#><#30437#>make-choice<#30437#> <#30438#>:<#30438#> <#30439#>(listof<#30439#> <#30440#>string)<#30440#> <#30441#><#30441#><#30442#>-;SPMgt;<#30442#><#30443#><#30443#> <#30444#>gui-item<#30444#><#65712#> <#71397#> 
<#30445#>;; to create a choice menu that permits users to choose from some<#30445#> 
<#30446#>;; string alternatives <#30446#> 
<#71398#>;; <#65713#><#30447#>get-choice<#30447#> <#30448#>:<#30448#> <#30449#>gui-item[<#30449#><#30450#>choice%<#30450#><#30451#>]<#30451#> <#30452#><#30452#><#30453#>-;SPMgt;<#30453#><#30454#><#30454#> <#30455#>num<#30455#><#65713#> <#71398#> 
<#30456#>;; to determine which choice is currently selected in a choice-item <#30456#> 
<#30457#>;; the result is the 0-based index in the choice menu <#30457#> 
<#65714#>Figure: The <#30461#>gui.ss<#30461#> operations<#65714#>
Here we study the simplified GUI world of the teachpack <#30463#>gui.ss<#30463#>. Figure~#figguitp#30464> specifies the operations that the teachpack provides. The GUI manager is represented by the function <#65716#><#30466#>create-window<#30466#><#65716#>. Its contract and purpose statement are instructive. They explain that we create a window from a list. The function arranges these lists in a corresponding number of rows on the visible window. Each row is specified as a list of <#65717#><#30467#>gui-item<#30467#><#65717#>s. The data definition for <#65718#><#30468#>gui-item<#30468#><#65718#>s in figure~#figguitp#30469> shows that there are four different kinds:
text fields,
which are created with <#65719#><#30471#>(make-text<#30471#>\ <#30472#>a-string)<#30472#><#65719#> and allow users to enter arbitrary text into an area in the window;
buttons,
which are created with <#65720#><#30473#>(make-button<#30473#>\ <#30474#>a-string<#30474#><#30475#> <#30475#><#30476#>a-function)<#30476#><#65720#> and allow users to apply a function with the click of a mouse button;
choice menus,
which are created with <#65721#><#30477#>(make-choice<#30477#><#30478#> <#30478#><#30479#>a-list-of-strings)<#30479#><#65721#> and allow users to pick a choice from a specified set of choices; and
message fields,
which are created with <#65722#><#30480#>(make-message<#30480#><#30481#> <#30481#><#30482#>a-string)<#30482#><#65722#> and enable the model to inform users of results.
The function that goes with a button is a function of one argument: an event. For most uses, we can ignore the event; it is simply a token that signals the user's click action. How all this works is best illustrated with examples. Our first example is a canonical GUI program:
<#30488#>(create-window<#30488#> <#30489#>(list<#30489#> <#30490#>(list<#30490#> <#30491#>(make-button<#30491#> <#30492#>``Close''<#30492#> <#30493#>hide-window))))<#30493#>
It creates a window with a single button and equips it with the simplest of all call-backs: <#65723#><#30497#>hide-window<#30497#><#65723#>, the function that hides the window. When the user clicks the button labeled <#65724#><#30498#>``Close''<#30498#><#65724#>, the window disappears. The second sample GUI copies what the user enters into a <#30499#>text<#30499#> field to a <#30500#>message<#30500#> field. We first create a <#30501#>text<#30501#> field and a <#30502#>message<#30502#> field:
<#30507#>(d<#30507#><#30508#>efine<#30508#> <#30509#>a-text-field<#30509#>
  <#30510#>(make-text<#30510#> <#30511#>``Enter<#30511#> <#30512#>Text:''))<#30512#> 
<#30513#>(d<#30513#><#30514#>efine<#30514#> <#30515#>a-message<#30515#> 
  <#30516#>(make-message<#30516#> <#30517#>```<#30517#><#30518#>Hello<#30518#> <#30519#>World'<#30519#> <#30520#>is<#30520#> <#30521#>a<#30521#> <#30522#>silly<#30522#> <#30523#>program.''))<#30523#> 
Now we can refer to these fields in a call-back function:
<#71400#>;; <#65725#><#30531#>echo-message<#30531#> <#30532#>:<#30532#> <#30533#>X<#30533#> <#30534#><#30534#><#30535#>-;SPMgt;<#30535#><#30536#><#30536#> <#30537#>true<#30537#><#65725#><#71400#>
<#71401#>;; to extract the contents of <#65726#><#30538#>a-text-field<#30538#><#65726#> and to draw it into <#65727#><#30539#>a-message<#30539#><#65727#> <#71401#> 
<#30540#>(d<#30540#><#30541#>efine<#30541#> <#30542#>(echo-message<#30542#> <#30543#>e)<#30543#> 
  <#30544#>(draw-message<#30544#> <#30545#>a-message<#30545#> <#30546#>(text-contents<#30546#> <#30547#>a-text-field)))<#30547#> 
The definition of the call-back function is based on our (domain) knowledge about the <#65728#><#30551#>gui-item<#30551#><#65728#>s. Specifically, the function <#65729#><#30552#>echo-message<#30552#><#65729#> obtains the current contents of the <#30553#>text<#30553#> field with <#65730#><#30554#>text-contents<#30554#><#65730#> as a string, and it draws this string into the <#30555#>message<#30555#> field with the <#65731#><#30556#>draw-message<#30556#><#65731#> function. To put everything together, we create a window with two rows:
<#30561#>(<#30561#><#30562#>create-window<#30562#>
 <#30563#>(list<#30563#> <#30564#>(list<#30564#> <#30565#>a-text-field<#30565#> <#30566#>a-message)<#30566#> 
       <#30567#>(list<#30567#> <#30568#>(make-button<#30568#> <#30569#>``Copy<#30569#> <#30570#>Now''<#30570#> <#30571#>echo-message))))<#30571#> 
The first row contains the <#30575#>text<#30575#> and the <#30576#>message<#30576#> field; the second one contains a button with the label <#65732#><#30577#>``Copy<#30577#>\ <#30578#>Now''<#30578#><#65732#> whose call-back function is <#65733#><#30579#>echo-message<#30579#><#65733#>. The user can now enter text into the <#30580#>text<#30580#> field, click the button, and see the text appear in the <#30581#>message<#30581#> field of the window. The purpose of the third and last example is to create a window with a choice menu, a message field, and a button. Clicking the button puts the current choice into the message field. As before, we start by defining the input and output <#65734#><#30582#>gui-item<#30582#><#65734#>s:
<#30587#>(d<#30587#><#30588#>efine<#30588#> <#30589#>THE-CHOICES<#30589#>
  <#30590#>(list<#30590#> <#30591#>``green''<#30591#> <#30592#>``red''<#30592#> <#30593#>``yellow''))<#30593#> 
<#30594#>(d<#30594#><#30595#>efine<#30595#> <#30596#>a-choice<#30596#> 
  <#30597#>(make-choice<#30597#> <#30598#>THE-CHOICES))<#30598#> 
<#30599#>(d<#30599#><#30600#>efine<#30600#> <#30601#>a-message<#30601#> 
  <#30602#>(make-message<#30602#> <#30603#>(first<#30603#> <#30604#>THE-CHOICES)))<#30604#> 
Because the list of choices is used more than once in the program, it is specified in a separate variable definition. As before, the call-back function for the button interacts with <#65735#><#30608#>a-choice<#30608#><#65735#> and <#65736#><#30609#>a-message<#30609#><#65736#>:
<#71402#>;; <#65737#><#30614#>echo-choice<#30614#> <#30615#>:<#30615#> <#30616#>X<#30616#> <#30617#><#30617#><#30618#>-;SPMgt;<#30618#><#30619#><#30619#> <#30620#>true<#30620#><#65737#><#71402#>
<#71403#>;; to determine the current choice of <#65738#><#30621#>a-choice<#30621#><#65738#> and<#71403#> 
<#71404#>;; to draw the corresponding string into <#65739#><#30622#>a-message<#30622#><#65739#> <#71404#> 
<#30623#>(d<#30623#><#30624#>efine<#30624#> <#30625#>(echo-choice<#30625#> <#30626#>e)<#30626#> 
  <#30627#>(draw-message<#30627#> <#30628#>a-message<#30628#> 
                <#30629#>(list-ref<#30629#> <#30630#>THE-CHOICES<#30630#> 
                          <#30631#>(choice-index<#30631#> <#30632#>a-choice))))<#30632#> 
Specifically, the call-back functionq determines the <#65740#><#30636#>0<#30636#><#65740#>-based index of the user's current choice with <#65741#><#30637#>choice-index<#30637#><#65741#>, uses Scheme's <#65742#><#30638#>list-ref<#30638#><#65742#> function to extract the corresponding <#30639#>string<#30639#> from <#65743#><#30640#>THE-CHOICES<#30640#><#65743#>, and then draws the result into the message field of the window. To create the window, we arrange <#65744#><#30641#>a-choice<#30641#><#65744#> and <#65745#><#30642#>a-message<#30642#><#65745#> in one row and the button in a row below:
<#30647#>(<#30647#><#30648#>create-window<#30648#>
 <#30649#>(list<#30649#> <#30650#>(list<#30650#> <#30651#>a-choice<#30651#> <#30652#>a-message)<#30652#> 
       <#30653#>(list<#30653#> <#30654#>(make-button<#30654#> <#30655#>``Confirm<#30655#> <#30656#>Choice''<#30656#> <#30657#>echo-choice))))<#30657#> 

<#65746#>;; <#30665#>Model<#30665#>:<#65746#>
<#71405#>;; <#65747#><#30666#>build-number<#30666#> <#30667#>:<#30667#> <#30668#>(listof<#30668#> <#30669#>digit)<#30669#> <#30670#><#30670#><#30671#>-;SPMgt;<#30671#><#30672#><#30672#> <#30673#>number<#30673#><#65747#><#71405#> 
<#30674#>;; to translate a list of digits into a number<#30674#> 
<#71406#>;; example: <#65748#><#30675#>(build-number<#30675#> <#30676#>(list<#30676#> <#30677#>1<#30677#> <#30678#>2<#30678#> <#30679#>3))<#30679#> <#30680#>=<#30680#> <#30681#>123<#30681#><#65748#><#71406#> 
<#30682#>(define<#30682#> <#30683#>(build-number<#30683#> <#30684#>x)<#30684#> <#30685#>...)<#30685#> 
<#65749#>;; <#65749#> 
<#65750#>;; <#30688#>View<#30688#>:<#65750#> 
<#30689#>;; the ten digits as strings <#30689#> 
<#30690#>(d<#30690#><#30691#>efine<#30691#> <#30692#>DIGITS<#30692#> 
  <#30693#>(build-list<#30693#> <#30694#>10<#30694#> <#71407#><#65751#><#30695#>number<#30695#><#65751#><#65752#><#30696#><#30696#><#30697#>-;SPMgt;<#30697#><#30698#><#30698#><#65752#><#65753#><#30699#>string<#30699#><#65753#><#71407#><#30700#>))<#30700#> 
<#30701#>;; a list of three digit choice menus <#30701#> 
<#30702#>(d<#30702#><#30703#>efine<#30703#> <#30704#>digit-choosers<#30704#> 
  <#30705#>(build-list<#30705#> <#30706#>3<#30706#> <#30707#>(lambda<#30707#> <#30708#>(i)<#30708#> <#30709#>(make-choice<#30709#> <#30710#>DIGITS))))<#30710#> 
<#65754#>;; a <#30711#>message<#30711#> field for saying hello and displaying the number <#65754#> 
<#30712#>(d<#30712#><#30713#>efine<#30713#> <#30714#>a-msg<#30714#> 
  <#30715#>(make-message<#30715#> <#30716#>``Welcome''))<#30716#> 
<#65755#>;; <#65755#> 
<#65756#>;; <#30719#>Controller<#30719#>: <#65756#> 
<#71408#>;; <#65757#><#30720#>check-call-back<#30720#> <#30721#>:<#30721#> <#30722#>X<#30722#> <#30723#><#30723#><#30724#>-;SPMgt;<#30724#><#30725#><#30725#> <#30726#>true<#30726#><#65757#><#71408#> 
<#30727#>;; to get the current choices of digits, convert them to a number, <#30727#> 
<#65758#>;; and to draw this number as a string into the <#30728#>message<#30728#> field <#65758#> 
<#30729#>(d<#30729#><#30730#>efine<#30730#> <#30731#>(check-call-back<#30731#> <#30732#>b)<#30732#> 
  <#30733#>(draw-message<#30733#> <#30734#>a-msg<#30734#> 
                <#30735#>(<#30735#><#71409#><#65759#><#30736#>number<#30736#><#65759#><#65760#><#30737#><#30737#><#30738#>-;SPMgt;<#30738#><#30739#><#30739#><#65760#><#65761#><#30740#>string<#30740#><#65761#><#71409#> 
                 <#30741#>(<#30741#><#30742#>build-number<#30742#> 
                  <#30743#>(map<#30743#> <#30744#>choice-index<#30744#> <#30745#>digit-choosers)))))<#30745#> 
<#30746#>(<#30746#><#30747#>create-window<#30747#> 
 <#30748#>(<#30748#><#30749#>list<#30749#> 
  <#30750#>(append<#30750#> <#30751#>digit-choosers<#30751#> <#30752#>(list<#30752#> <#30753#>a-msg))<#30753#> 
  <#30754#>(list<#30754#> <#30755#>(make-button<#30755#> <#30756#>``Check<#30756#> <#30757#>Guess''<#30757#> <#30758#>check-call-back))))<#30758#> 
<#30762#>Figure: A GUI for echoing digits as numbers<#30762#>
Now that we have examined some basic GUI programs, we can study a program with full-fledged core and GUI components. Take a look at the definitions in figure~#figcopymany#30764>. The program's purpose is to echo the values of several digit choice menus as a number into some message field. The model consists of the <#65762#><#30765#>build-number<#30765#><#65762#> function, which converts a list of (three) digits into a number. We have developed several such functions, so the figure only mentions what it does. The GUI component of the program sets up three choice menus, a message field, and a button. The control part consists of a single call-back function, which is attached to the single button in the window. It determines the (list of) current choice indices, hands them over to <#65763#><#30766#>build-number<#30766#><#65763#>, and draws the result as a string into the message field. Let's study the organization of the call-back functions in more detail. It composes three kinds of functions:
  1. The innermost function determines the current state of the <#65764#><#30768#>gui-item<#30768#><#65764#>s. This is the user's input. With the given functions, we can either determine the string that the user entered into a text field or the 0-based index of a choice menu.
  2. This user input is consumed by the main function of the model. The call-back function may convert the user's string into some other data, say, a symbol or a number.
  3. The result of the model function, in turn, is drawn into a message field, possibly after converting it to a string first.
The control component of a program is also responsible for the visual composition of the window. The teachpack provides only one function for this purpose: <#65765#><#30770#>create-window<#30770#><#65765#>. Standard GUI toolboxes provide many more functions, though all of these toolboxes differ from each other and are changing rapidly.
<#30773#>Exercise 22.3.1<#30773#> Modify the program of figure~#figcopymany#30775> so that it implements the number-guessing game from exercises~#exguess1#30776>, #exguess2#30777>, and~#exguess3#30778>. Make sure that the number of digits that the player must guess can be changed by editing a single definition in the program. <#30779#>Hint:<#30779#> Recall that exercise~#exrandom#30780> introduces a function that generates random numbers.~ external Solution<#65766#><#65766#> <#30786#>Exercise 22.3.2<#30786#> Develop a program for looking up phone numbers. The program's GUI should consist of a <#30788#>text<#30788#> field, a message field, and a button. The <#30789#>text<#30789#> field permits users to enter names. The message field should display the number that the model finds or the message <#65767#><#30790#>``name<#30790#>\ <#30791#>not<#30791#>\ <#30792#>found''<#30792#><#65767#>, if the model produces <#65768#><#30793#>false<#30793#><#65768#>. Generalize the program so that a user can also enter a phone number (as a sequence of digits containing no other characters).

<#30794#>Real-world GUIs<#30794#>:\ The graphical user interface in figure~#figlookupgui#30795> was not constructed from the items provided by the teachpack. GUIs constructed with the teachpack's <#65769#><#30796#>gui-item<#30796#><#65769#>s are primitive. They are sufficient, however, to study the basic principles.~<#65770#><#65770#> <#30799#>Hints:<#30799#> (1) Scheme provides the function <#71410#><#65771#><#30800#>string<#30800#><#65771#><#65772#><#30801#><#30801#><#30802#>-;SPMgt;<#30802#><#30803#><#30803#><#65772#><#65773#><#30804#>symbol<#30804#><#65773#><#71410#> for converting a string to a symbol. (2) It also provides the function <#71411#><#65774#><#30805#>string<#30805#><#65774#><#65775#><#30806#><#30806#><#30807#>-;SPMgt;<#30807#><#30808#><#30808#><#65775#><#65776#><#30809#>number<#30809#><#65776#><#71411#>, which converts a string to a number if possible. If the function consumes a string that doesn't represent a number, it produces <#65777#><#30810#>false<#30810#><#65777#>:

  <#30815#>(<#30815#><#65778#><#30816#>string<#30816#><#65778#><#65779#><#30817#><#30817#><#30818#>-;SPMgt;<#30818#><#30819#><#30819#><#65779#><#65780#><#30820#>number<#30820#><#65780#> <#30821#>``6670004'')<#30821#>
<#30822#>=<#30822#> <#30823#>6670004<#30823#> 
  <#30831#>(<#30831#><#65781#><#30832#>string<#30832#><#65781#><#65782#><#30833#><#30833#><#30834#>-;SPMgt;<#30834#><#30835#><#30835#><#65782#><#65783#><#30836#>number<#30836#><#65783#> <#30837#>``667-0004'')<#30837#>
<#30838#>=<#30838#> <#30839#>false<#30839#> 
The generalization demonstrates how one and the same GUI can use two distinct models.~ external Solution<#65784#><#65784#> <#30848#>Exercise 22.3.3<#30848#> Develop <#71412#><#65785#><#30850#>pad<#30850#><#65785#><#65786#><#30851#><#30851#><#30852#>-;SPMgt;<#30852#><#30853#><#30853#><#65786#><#65787#><#30854#>gui<#30854#><#65787#><#71412#>. The function consumes a title (string) and a <#65788#><#30855#>gui-table<#30855#><#65788#>. It turns the table into a list of lists of <#65789#><#30856#>gui-item<#30856#><#65789#>s that <#65790#><#30857#>create-window<#30857#><#65790#> can consume. Here is the data definition for <#65791#><#30858#>gui-table<#30858#><#65791#>s:
A <#65792#><#30860#>gui-table<#30860#><#65792#> is a <#65793#><#30861#>(listof<#30861#>\ <#30862#>(listof<#30862#>\ <#30863#>cell))<#30863#><#65793#> .
A <#65794#><#30866#>cell<#30866#><#65794#> is either
  1. a number,
  2. a symbol.
Here are two examples:
<#30874#>(d<#30874#><#30875#>efine<#30875#> <#30876#>pad<#30876#>
  <#30877#>'<#30877#><#30878#>(<#30878#><#30879#>(1<#30879#> <#30880#>2<#30880#> <#30881#>3)<#30881#> 
    <#30882#>(4<#30882#> <#30883#>5<#30883#> <#30884#>6)<#30884#> 
    <#30885#>(7<#30885#> <#30886#>8<#30886#> <#30887#>9)<#30887#> 
    <#30888#>(\<#30888#><#30889#>#<#30889#> <#30890#>0<#30890#> <#30891#>*)))<#30891#> 
<#30898#>(d<#30898#><#30899#>efine<#30899#> <#30900#>pad2<#30900#> 
  <#30901#>'<#30901#><#30902#>(<#30902#><#30903#>(1<#30903#> <#30904#>2<#30904#> <#30905#>3<#30905#>  <#30906#>+)<#30906#> 
    <#30907#>(4<#30907#> <#30908#>5<#30908#> <#30909#>6<#30909#>  <#30910#>-)<#30910#> 
    <#30911#>(7<#30911#> <#30912#>8<#30912#> <#30913#>9<#30913#>  <#30914#>*)<#30914#> 
    <#30915#>(0<#30915#> <#30916#>=<#30916#> <#30917#>\<#30917#><#30918#>.<#30918#> <#30919#>/)))<#30919#> 
The table on the left lays out a virtual phone pad, the right one a calculator pad. The function <#71413#><#65795#><#30923#>pad<#30923#><#65795#><#65796#><#30924#><#30924#><#30925#>-;SPMgt;<#30925#><#30926#><#30926#><#65796#><#65797#><#30927#>gui<#30927#><#65797#><#71413#> should turn each cell into a button. The resulting list should be prefixed with two messages. The first one displays the title and never changes. The second one displays the latest button that the user clicked. The two examples above should produce the following two GUIs: rawhtml40 <#30928#>Hint:<#30928#> The second message header requires a short string, for example, <#65798#><#30929#>``N''<#30929#><#65798#>, as the initial value.~ external Solution<#65799#><#65799#>