1B MicroScript Thorough Primer, No. 7

Toshihisa Muto

Personal Media Corporation


How to create a parts library that we can call up from 1B MicroScript will be continued. On this occasion, we will create a text box in which we can input numerical values.

In the previous installment and the installment prior that in this series, we took up a parts library that can be used from MicroScript. The parts that were made the subject are an ON/OFF switch, selectors, and volume controls. A settings screen that uses these parts on the screen was easily created just by calling up a few procedures. Accordingly, on this occasion, we will take up a text box as the third part in our discussion of parts libraries.

What's a Text Box?

In BTRON, we call parts in which we can input characters a "text box" or a "character box." Even in MicroScript, we can realize this box using the INPUT statement. Actually, I already explained this INPUT statement in the second installment (Vol. 23 of this magazine). However, this statement was prepared for the purpose of controlling in a detailed manner input from the keyboard, and thus it possesses aspects that are a little difficult in employing it in text box use.

For that reason, covering one more layer on top of this and making a library is the subject of this installment.

Furthermore, that which can be handled in the current version of MicroScript are only numerical values. Although we can use character strings in a portion of the output formats, we cannot do such things as store them in variable or control character strings. Accordingly, the text box that we will create on this occasion, strictly speaking, will be a "numerical value box."

Figure 1. Lighting time settings panel

Control Panel that Uses a Text Box

Let's create the Lighting Time Setting control panel in Fig. 1 using a text box library. In this text box, four text boxes are arranged. Characters input from the keyboard are entered at the location of the cursor (). Because we cannot input anything other than numerals, the displays are all are right justified. Corrections are possible with the [Backspace] key. When you push the [TAB] key, the cursor moves to the next text box. The cursor moves there even if you directly click the text box.

Figure 2. Displaying the current values in the message area

As we have done up to here, because the main point of the programming lies in the creation of a user interface, actual lighting control will not be carried out at all. In order to confirm the setting values, we will attach only a function through which the current settings appear in the message area when the user selects [Show Current Values] from the [Control] menu (Fig. 2).

Figure 3. Segment definitions in the Lighting Time Settings panel

Defining the Segments

As for defining the segments, we create them as in Fig. 3 using the figure editor. Because they are rather packed together, I shall go through and explain them one by one.

The segment label0 is something in which we have grouped together the "Turn On Time:" label with the ":" that connects the hours and minutes. The segment txt00 forms a text box for inputting the "hour" of the turn on time. Two spaces have been entered so that two place numerals can be entered. The segment txt01 is for use in the input of the "minutes." The segments label1, txt10, and txt11 form the same segment organization concerning the turn off time.

SCRIPT: Common

This is a common script necessary in the utilization of a parts library for selectors (including switches), volume controls, and text boxes. The definition of such things as integers are carried out here.

SCRIPT: Text Box

This is the script that realizes the text box library. Just by entering this script, it comes about that the text box library can be used. If you just understand the method of calling up the library, it is not necessary to understand the contents of this script.

SCRIPT: Lighting Time Settings

This is a script for the lighting time settings panel. Actually, this alone is fine for what the user will program with.

Realizing the Text Boxes

Well then, let's try doing the programming that calls up the text library. I would like you to look at Program 3 "SCRIPT: Lighting Time Settings."

Procedure "Initialize_TxtBx"

As always, I will follow through the procedure one by one in the order in which things are executed. When you open this MicroScript window, the very first thing that is executed is the part enclosed with PROLOGUE and END on the 56th to 78th lines. Through the 57th to the 59th lines, we make the program display all the segments on the screen. Next, through the 60th line, we execute the following statement.

60 CALL Initialize_TxtBx

Before we use the text box library, it is necessary, without fail, to call up the procedure "Initialize_TxtBx" just once.

Procedure "Register_TxtBx"

Through the 61st line, we call up the procedure "Register_TxtBx," and we register a text box. Within the turn on time, this is the registration of the text box side in which we enter the "hour."

61 CALL Register_TxtBx txt00 0 23 TrnOn_Time_Hr

The respective arguments possess the following meanings.

No. 0 argument: <text box segment>
No. 1 argument: <text box minimum value>
No. 2 argument: <text box maximum value>
No. 3 argument: <execution procedure when input ends>
No. 4 argument:
<fill in 0 to the left of the numerical value?>
left 0 fill-in (=1) fill in
0, not specified don't fill in

Because the "hour" is entered into the segment txt00, we specify "0" and "23" respectively for the minimum value and the maximum value. In the no. 3 argument, we specify the name of a procedure that is called up at the time character input into this segment ends. In this case, because we have specified the procedure "TrnOn_Time_Hr," we come to separately prepare and put in place a procedure of this name.

What we call the end of input actually means when one key among the [TAB] key, [Return] key, or [Execute] key has been pressed. In the text box specification of BTRON, when these keys are pressed, input becomes fixed, and that value passes to the system. It exactly matches with the operations that fix kana-to-kanji conversion results. Once input has been fixed, control returns to the procedure that is specified with the no. 3 argument.

Through <execution procedure when input ends> (here, "TrnOn_Time_Hr"), we carry out a check as to whether the value that has been fixed falls within the minimum value and the maximum value. For the actual check, we call up the the library procedure "TxtBx_Value_Check" (described below).

When we specify "fill in zero to the left" in the no. 4 argument, the left side of the right-aligned numerical value gets filled with a "0." "Fill in zero to the left" is defined with "1" in "SCRIPT: Common."

When we call up the procedure "Register_TxtBx," the text box ID is returned as the return value. Actually, an integer value of 0 or greater is used; in line 62nd line, with

62 SET txtid00 ret

we store the text box ID in the variable txtid00. In a case where registration fails, the return value becomes negative, but here the error check is omitted.

Procedure "Set_TxtBx"

We set the value that enters the text box with the 63rd line.

63 CALL Set_TxtBx txtid00 8

The arguments of the procedure "Set_TxtBx" are as follows:

No. 0 argument: <text box ID>
No. 1 argument: <setting value>

Of course, it is necessary for the <setting value> to be kept in the range of the minimum value and the maximum value specified with "Register_TxtBx."

In the 61st to the 63rd lines, the registration of the "hour" part of the "turn on time" and the setting of the initial value are finished. In the 65th through 75th lines, we carrying out the settings concerning the remaining three text boxes. As the initial settings, we have set "8:00" in the turn on time, and "20:05" in the turn off time. In the no. 4 argument of the procedure "Register_TxtBx," I want you to pay attention to notice whether or not we have set "fill in zero to the left." It is not specified in the "hour" text box, rather it is specified in the "minute."

Procedure "TxtBx_Active"

In the 77th line, we call up the procedure "TxtBx_Active."

77 CALL TxtBx_Active txtid00

No. 0 argument: <text box ID>

What we call active means a state in which the cursor exists there, and in which we can input numerical values. When we use the procedure "TxtBx_Active," the specified text box becomes active. Here, the cursor appears in txtid00, in other words, in the "hour" text box of the "turn on time."

After this, by pressing the [TAB] key or directly clicking on a text box, we make the text box active. The order in which the cursor moves when we have pressed the [TAB] key is the order in which we have called up the procedure "Register_TxtBx."

Processing When the Text Box Has Been Fixed (8th to 49th Lines)

In the 8th to 49th lines, I have described the processing for when a text box has been clicked, or a value has been fixed by means of the [TAB] key, etc. In using the text boxes, outside of registering them, this type of procedure description becomes necessary.

Processing When the Text Box Has Been Clicked (15th to 49th Lines)

In the 15th to the 49th lines, almost the same processing is being carried out in regard to the four text boxes. Accordingly, for the actual explanation, I will give it only for the 15th to 22nd lines of the processing in regard to the "hour" text box of the "turn on time."

When the "hour" text box of the "turn on time" is clicked, control moves to the procedure "TrnOn_Time_Hr_Clicked." First, with

16  CALL All_Values_Check

we investigate whether the input values for all the text boxes have been kept within the proper range. Actually, we call up the library procedure "TxtBx_Value_Check."

CALL TxtBx_Value_Check txtid00 txt00.V

No. 0 argument: <text box ID>
No. 1 argument: <current value>

When we attach the state name (refer to Vol. 23 of this magazine) ".V" to a text segment name, the current value that is stored in that text box is obtained. We give this as the no. 1 argument of "TxtBx_Value_Check." In this procedure, we check whether the value of the no. 1 argument has been kept within the range of the minimum value and the maximum value specified with "Register_TxtBx." If it hasn't been kept within these, it ends up being forcibly rewritten into either the minimum value or the maximum value.

For example, because we have specified the range of "hour" from 0 to 23 (61st, 69th lines), if someone inputs 25, then the program will forcibly set to the maximum value of 23.

The procedure "All_Values_Check" investigates whether all the values of the text boxes have been kept within their ranges. However, in actuality, it is fine if it only checks just the value of the text box that was active just before. In order to realize that, the following library procedure has also been prepared.

Procedure "Acquire_Active_TxtBx"
No. 0 argument: <text box ID>
Return value Current active text box ID (0~)

If we use this, we can check only the necessary text box using the library procedure "TxtBx_Value_Check." However, because the processing for that becomes a little complicated, here I have adopted the simple method of calling up the procedure "All_Values_Check."

Well then, in the 17th line, we specify the active text box in the line itself. By doing this, the cursor moves to the segment txt00. In other words, the text segment that has been clicked becomes active.

17  CALL TxtBx_Active txtid00

Processing When the Text Box Input Has Been Fixed (20th to 22nd Lines)

When you press the [TAB] key, [Return] key, or [Execute] key, control moves to the procedure specified in the no. 3 argument of the procedure "Register_TxtBx" in regard to the currently active text box. For example, in a case where the "hour" of the "turn on time" was active, it would come about that control would move to the procedure "TrnOn_Time_Hr" [Note].

20 ACTION TrnOn_Time_Hr
21  TrnOn_Time_HrCheck
22 END

"TrnOn_Time_HrCheck" is defined in a DEFINE statement, and in the end it calls up the procedure "TxtBx_Value_Check," and then it investigates whether or not the values of the text boxes have been kept within their ranges.

EPILOGUE (80th to 82nd Lines)

80 EPILOGUE
81   CALL Exit_TxtBx
82 END

Between EPILOGUE and END is a statement that is executed when the MicroScript window has been closed. Here, we execute the procedure "Exit_TxtBx." This procedure is solely for calling up <execution procedure when input ends> in regard to the text box that was last active. The reason we call this up is for the purpose of making it so that a check of values is properly carried out even when the user ends up closing the window without pressing either the [TAB] key, [Return] key, or [Execute] key, after he/she has changed the contents of the text box.

"SCRIPT: Common," "SCRIPT: Text Box"

As of up to here, the explanation of "SCRIPT: Lighting Time Settings" is finished." In "SCRIPT: Common" and "SCRIPT: Text Box," the text box library below that was used has been programmed.

Procedure "Initialize_TxtBx"
Procedure "Register_TxtBx"
Procedure "Set_TxtBx"
Procedure "TxtBx_Active"
Procedure "Acquire_Active_TxtBx"
Procedure "TxtBx_Value_Check"
Procedure "Exit_TxtBx"

Because I have relatively thoroughly attached comments to "SCRIPT: Text Box," I shall forego explaining this in detail in this article.

The TEXT statement that is used inside this is explained in the second installment of this series (Vol. 23 of this magazine).

I would like to mention only one thing for future reference. In displaying numerical values right aligned in a text box, it is necessary to know the number of places of the numerical values. For example, in displaying at a maximum a three-place numerical value, we prepare and put in place beforehand a text segment in which we have entered three places. And then, it is necessary to make the expression specification of the TEXT statement as

"%3d"

in displaying the numerical values right aligned here. In the text box library, by searching for the number of places of the maximum value, we obtain the information required in the expression specification of the TEXT statement. However, that which supports the right-aligned display of a numerical values display is up to four places. Numerical values that exceed that are displayed left aligned.

In Closing

Over three installments, we have created a parts library of selectors (including switches), volume controls, and text boxes, and I have described in detail the procedures for calling up this library. I think that you will be able to create a fair number of settings screens, if you use these three parts.

____________________

Program 1 "SCRIPT: Common"
 1 DEFINE MAXVOL 4  # Maximum number of volume controls
 2 DEFINE MAXSEL 4  # Maximum number of selectors (switches)
 3 DEFINE MAXTXT 4  # Maximum number of text boxes
 4 DEFINE MAXELM 24 # MAXSEL x MAXCHOICE (=6)
 5
 6 DEFINE pid $ARG[0] # Use first argument as PID
 7
 8 DEFINE Zero_Right_Justified 1
 9
10 VARIABLE ret # Variable into which we enter a procedure's return value

Program 2 "SCRIPT: Text Box"
  1 DEFINE _t_TAB 9   # TAB key
  2 DEFINE _t_EXEC 4  # Execute key
  3 DEFINE _RET   10  # Return key
  4 #
  5 # Variables used in text box parts
  6 # We attach _ at the beginning to variables in which we store segments
  7 VARIABLE _t_l                 # Counter
  8 VARIABLE _t_ntxt              # Number of registered text boxes
  9 VARIABLE __t_txt [MAXTXT]     # Text box segment
 10 VARIABLE _t_func [MAXTXT]     # Function executed at time input ends
 11 VARIABLE _t_min [MAXTXT]      # Minimum value
 12 VARIABLE _t_max [MAXTXT]      # Maximum value
 13 VARIABLE _t_dig [MAXTXT]      # Maximum number of places
 14 VARIABLE _t_fillzero [MAXTXT] # Fill in 0 to left of numerical value?
 15 VARIABLE _t_active            # Active box
 16
 17 #--------------------------------------------------------------------
 18 ACTION Initialize_TxtBx
 19  SET _t_ntxt 0
 20  SET _t_active 0
 21 END
 22
 23 #--------------------------------------------------------------------
 24 # Registering the text box
 25 #   Register_TxtBx
 26 #   $ARG[0]:<text box segment>
 27 #   $ARG[1]:<text box minimum value>
 28 #   $ARG[2]:<text box maximum value>
 29 #   $ARG[3]:<function executed at time input ends>
 30 #   $ARG[4]:<fill in 0 to left of numerical value?>
    #           1=fill in; 0 or not specified=don't fill in 
 31 #   Return value <0 error
 32 #               >=0 TxtBx ID (0~)
 33 #
 34 DEFINE _t_tmp $ARG[7]
 35 ACTION Register_TxtBx
 36  IF _t_ntxt >= MAXTXT
 37   SET ret -1
 38   EXIT
 39  ENDIF
 40  SET __t_txt [_t_ntxt] $ARG[0]
 41  SET _t_min [_t_ntxt] $ARG[1]
 42  SET _t_max [_t_ntxt] $ARG[2]
 43  SET _t_func [_t_ntxt] $ARG[3]
 44  SET _t_fillzero [_t_ntxt] $ARG[4]
 45
 46  # Find number of places of maximum value and enter in _t_dig 
 47  SET _t_tmp 1
 48  REPEAT
 49   SET $ARG[2] $ARG[2]/10
 50   IF $ARG[2] == 0;BREAK;ENDIF
 51   SET _t_tmp _t_tmp +1
 52  ENDREPEAT
 53  SET _t_dig [_t_ntxt] _t_tmp
 54
 55  SET ret _t_ntxt
 56  SET _t_ntxt _t_ntxt +1
 57 END
 58
 59 DEFINE _t_newval $ARG[7]
 60 DEFINE TEXTOUT 
    IF _t_dig [_pid]== 2; 
     IF _t_fillzero [_pid] ==1;
       TEXT __t_txt [_pid]"%02d" $ARG[7];
        ELSE;
       TEXT __t_txt [_pid]"%2d" $ARG[7];
     ENDIF;
     ELSE;
     IF _t_dig [_pid]== 3; 
      IF _t_fillzero [_pid] ==1;
        TEXT __t_txt [_pid]"%03d" $ARG[7]; 
         ELSE;
        TEXT __t_txt [_pid]"%3d" $ARG[7];
     ENDIF;
     ELSE;
     IF _t_dig [_pid]== 4; 
      IF _t_fillzero [_pid] ==1;
        TEXT __t_txt [_pid]"%04d" $ARG[7]; 
         ELSE;
        TEXT __t_txt [_pid]"%4d" $ARG[7];
     ENDIF
     ELSE;
        TEXT __t_txt [_pid]"%d" $ARG[7];
     ENDIF;
     ENDIF;
    ENDIF
 61 #--------------------------------------------------------------------
 62 # Setting a value in the text box
 63 #   Set_TxtBx
 64 #      $ARG[0]:<text box ID>:pid(0~)
 65 #      $ARG[1]:<text box value>
 66 #   No return value
 67 ACTION Set_TxtBx
 68   SET _t_newval $ARG[1]
 69   TEXTOUT
 70 END
 71 #--------------------------------------------------------------------
 72 # Making the text box active
 73 #   TxtBx_Active
 74 #     $ARG[0]:<text box ID>:pid(0~)
 75 #   No return value
 76 ACTION TxtBx_Active
 77   SET _t_active $ARG[0]
 78   INPUT __t_txt [_t_active]
 79 END
 80 #--------------------------------------------------------------------
 81 # Acquiring the active text box ID
 82 #   Acquire_Active_TxtBx
 83 #   Return value  ID of the text box
 84 ACTION Acquire_Active_TxtBx
 85  SET ret _t_active
 86 END
 87 #--------------------------------------------------------------------
 88 # Exiting the text box
 89 #   Exit_TxtBx
 90 #   No return value
 91 ACTION Exit_TxtBx
 92  CALL _t_func [_t_active]
 93 END
 94 #--------------------------------------------------------------------
 95 # Text box value check
 96 #   TxtBx_Value_Check
 97 #     $ARG[0]:<text box ID>:pid (0~)
 98 #     $ARG[1]: current value
 99 #   No return value
100 DEFINE _t_value $ARG[1]
101 ACTION TxtBx_Value_Check
102   IF _t_value == 0
103   SET _t_newval 0
104   TEXTOUT
105   EXIT
106   ENDIF
107   IF _t_value > _t_max [_pid]
108     # When maximum value is exceeded, restrain to maximum value
109     SET _t_newval _t_max [_pid]
110     TEXTOUT
111   ELSE
112   IF _t_value < _t_min [_pid] 
113     # When value is below minimum value, restrain to minimum value
114     SET _t_newval _t_min [_pid]
115     TEXTOUT
116   ELSE
117     # Basically, this TEXTOUT is not necessary, but
118     # because there are cases when 0 is filled into the left
119     # we execute TEXTOUT
120     SET _t_newval _t_value
121     TEXTOUT
122   ENDIF
123   ENDIF
124 END
125 #--------------------------------------------------------------------
126 DEFINE _t_key $ARG[7]
127 ACTION _t_whenKeyIsPressed KEY
128   SET _t_key $KEY
129   IF _t_key==_t_TAB | _t_key==_t_EXEC | _t_key==_t_RET
130     # When these three keys are pushed,
131     # jump to the user specified input value check routine
132     CALL _t_func [_t_active] _t_key
133   ENDIF
134   IF _t_key == _t_TAB
135     # In the case of the TAB key, we move the caret to the next box
136   CALL TxtBx_Active (_t_active+1) %_t_ntxt
137   ENDIF
138 END

Program 3 "SCRIPT: Lighting Time Settings"
 1 VARIABLE txtid00 txtid01 txtid10 txtid11
 2 #---------------------------------------------------------------------
 3 DEFINE TrnOn_Time_HrCheck  CALL TxtBx_Value_Check txtid00 txt00.V
 4 DEFINE TrnOn_Time_MinCheck CALL TxtBx_Value_Check txtid01 txt01.V
 5 DEFINE TrnOff_Time_HrCheck  CALL TxtBx_Value_Check txtid10 txt10.V
 6 DEFINE TrnOff_Time_MinCheck CALL TxtBx_Value_Check txtid11 txt11.V
 7
 8 ACTION All_Values_Check
 9   TrnOn_Time_HrCheck
10   TrnOn_Time_MinCheck
11   TrnOff_Time_HrCheck
12   TrnOff_Time_MinCheck
13 END
14 #---------------------------------------------------------------------
15 ACTION TrnOn_Time_Hr_Clicked CLICK txt00
16  CALL All_Values_Check
17  CALL TxtBx_Active txtid00
18 END
19 
20 ACTION TrnOn_Time_Hr
21  TrnOn_Time_HrCheck
22 END
23 #---------------------------------------------------------------------
24 ACTION TrnOn_Time_Min_Clicked CLICK txt01
25  CALL All_Values_Check
26  CALL TxtBx_Active txtid01
27 END
28
29 ACTION TrnOn_Time_Min
30  TrnOn_Time_MinCheck
31 END
32 #---------------------------------------------------------------------
33 ACTION TrnOff_Time_Hr_Clicked CLICK txt10
34  CALL All_Values_Check
35  CALL TxtBx_Active txtid10
36 END
37
38 ACTION TrnOff_Time_Hr
39  TrnOff_Time_HrCheck
40 END
41 #---------------------------------------------------------------------
42 ACTION TrnOff_Time_Min_Clicked CLICK txt11
43  CALL All_Values_Check
44  CALL TxtBx_Active txtid11
45 END
46
47 ACTION TrnOff_Time_Min
48  TrnOff_Time_MinCheck
49 END
50 ######################################################################
51 ACTION Show_Current_Values MENU "Show Current Values"
52  MESG "TrnOn=%2d:%2d TrnOff=%2d:%2d" txt00.V txt01.V txt10.V txt11.V
53 END
54 
55 ######################################################################
56 PROLOGUE
57 DEFINE TrnOn_Time_Segment  label0 txt00 txt01
58 DEFINE TrnOff_Time_Segment label1 txt10 txt11
59 SCENE BACK TrnOn_Time_Segment TrnOff_Time_Segment
60 CALL Initialize_TxtBx
61 CALL Register_TxtBx txt00 0 23 TrnOn_Time_Hr
62 SET txtid00 ret
63 CALL Set_TxtBx txtid00 8
64 #---------------------------------------------------------------------
65 CALL Register_TxtBx txt01 0 59 TrnOn_Time_Min Zero_Right_Justified
66 SET txtid01 ret
67 CALL Set_TxtBx txtid01 0 # Turn on time initial value=8:00
68 #---------------------------------------------------------------------
69 CALL Register_TxtBx txt10 0 23 TrnOff_Time_Hr
70 SET txtid10 ret
71 CALL Set_TxtBx txtid10 20
72 #---------------------------------------------------------------------
73 CALL Register_TxtBx txt11 0 59 TrnOff_Time_Min Zero_Right_Justified
74 SET txtid11 ret
75 CALL Set_TxtBx txtid11 5 # Turn off time initial value=20:05
76 #---------------------------------------------------------------------
77 CALL TxtBx_Active txtid00
78 END
79 ######################################################################
80 EPILOGUE
81   CALL Exit_TxtBx
82 END
83 ######################################################################

____________________

[Note] Procedure that Executes at the Time Input Terminates: There might be readers who think that a mechanism in which control deliberately returns to a user procedure for a check of fixed values is unnatural. This is the cry of those who say, "in spite of it being fine if you just check for them automatically inside a library."

Certainly, I wanted to design the library in that manner, but in the current specification of the MicroScript language, there are the following limitations, and unavoidably things ended up like this.

For example, suppose that there is a segment with the name txt. In displaying in the message area the numerical values entered inside this, we attach the state name ".V" and make it in the following manner (refer to Vol. 23 of this magazine).

MESG "%d" txt.V

However, after substituting the segment txt temporarily in another variable, we cannot attach the state name .V to this variable and access it.

SET T txt
MESG "%d" T.V   # ← not possible

Accordingly, in the design of a text library, whether one likes it or not, the need arises to have the check of the numerical values range carried out in a user procedure. In other words, beyond making it so that a library can handle whichever text boxes that possess names, there is nothing other than a user procedure in which the specifications txt00.V, txt01.V, txt10.V, and txt11.V are possible.


The above article on MicroScript appeared on pages 94-101 in Vol. 29 of TRONWARE . It was translated and loaded onto this Web page with the permission of Personal Media Corporation.

Copyright © 1994 Personal Media Corporation

Copyright © 2008 Sakamura Laboratory, University Museum, University of Tokyo