ROLL YOUR OWN PROMPT

© 2003, Brad Moore

Home

Drawn Objects

Documenting Code

Tipcorner - Helpfile

Bmpbuttons

Prompt by Brad Moore

Locate Controls

Tips by Dennis McKinney

Demos by Bill Jennings

Review of TheWrap

Integration by Tom Nally

SQLite by Richard Peeters

Help Writing by Jerry Muelver

Index

Roll Your Own Prompt

by Brad Moore - article is copyright 2003

I am a long time user of Liberty Basic, dating back to the version 1.31 or earlier. Through out all this time there have been a lot of things I have heard people ask Carl to add or fix or enhance. One of the more popular has been the PROMPT function. Here it what the help file says about the Prompt function:

PROMPT string; responseVar$

Description:

The PROMPT statement opens a dialog box, displays string, and waits for the user to type a response and press 'Return' (or press the OK or Cancel button). The entered information is placed in responseVar$. If Cancel is pressed, then a string of zero length is returned. If responseVar is set to some string value before PROMPT is executed, then that value will become the 'default' or suggested response. This means that when the dialog is opened, the contents of responseVar$ will already be entered as a response for the user, who then has the option to either type over that 'default' response, or to press 'Return' and accept it.

The prompt function has received a lot of attention be cause it seems to lack some of the functionality and design finesse of its two cousins the NOTICE function and the CONFIRM function. Both the NOTICE and the CONFIRM function allow multiple lines of text to be displayed, where the PROMPT function only supports one line of text. Additionally the NOTICE function allows the programmer to apply a custom title to the titlebar of the NOTICE dialog window.

An additional problem has also crept into the equation - when using a PROMPT it is not possible to set a timer, call the PROMPT function and then allow the timer to force a return from the PROMPT function. The call to the PROMPT function appears to shut the timer down. This prevents the user from making a PROMPT function that automatically times out and then selects a default value should the user have not entered something of their own. A desirable feature sometimes.

I have often suggest that the programmer who is dissatisfied with the features of the PROMPT function should simply write their own custom PROMPT function, but few seem to be interested in doing this. So I have taken the several most common complaints and compiled them into a list of features for a modular PROMPT replacement function. The function needs to support the following:

All the general features of the standard LB PROMPT function

A programmable title for the titlebar that will display a default if not provided

The ability to display multiple lines

The ability to automatically time out and close the window after a specified period

Encapsulated into a reusable function

Part way through programming an interesting discussion on the Liberty Basic Group List grabbed my attention. It centered around a pitfall that one can easily get them selves into when they encapsulate a window with controls into a function or sub program that is called from another program. The problem is a bit complex, but I wanted to talk about it, as it is important to understand so one can understand how and why the function works. The real issue is a problem of scope. If I cause a program to stop and wait in a function of sub program (even using a scan command) and it gets an event that the user has triggered by pressing a button, for example, the branch label to which the event is associated will not be visible to the program from with in the function or sub program and there will be an error. That is because LB specifies branch labels as local to the area of code where they occur. If the label [quit] is in the main part of the program, but I am in the sub program called SMILE then I can not see the branch label [quit] - it just does not exist.

This is important to recognize (and I initially failed to recognize this) because my custom function had a dialog window with controls and a WAIT statement to wait for the user to press the controls. But what if the user moved my dialog window out of the way and press a control on the window that spawned my dialog window - ERROR! The answer was to open the dialog as a modal window. The modal dialog window will disable the controls on all other windows associated with that program and only allow the current window to have focus. LB's implementation of modal is simply program wide and not system wide (there is a windows intrinsic to do that too), so other programs continue to operate.

So having conquered that the rest was fairly straight forward. I have commented the program function fairly well, so I will let the function speak for itself. Just a couple last words. I have released the function and the demo program into the public domain. You may do with them as you wish. The article (the parts that preceded the code) is not released into the public domain. If you use or alter my function it is not necessary to credit me. As a public domain source it is yours. I hope people will use it and change it and grow it. Have fun...

'----------------------------------------------------------------------------
'Demo the "Roll Your Own Prompt" by Brad Moore
'The function and demo written in Jan 2003
'Both the function and the demo are released to the 
'public domain as of Jan 2003.  Please use them for
'good everywhere.
'
'Written in Liberty Basic - ver 3.x - using Liberty Workshop
'For more information about Liberty Basic please visit the
'website http://www.libertybasic.com


[InitColors]
    ForegroundColor$ = "Black"
    BackgroundColor$ = "Buttonface"
    TexteditorColor$ = "White"
    TextboxColor$    = "White"
    ComboboxColor$   = "White"
    ListboxColor$    = "White"

[WindowSetup]
    NoMainWin
    WindowWidth = 490 : WindowHeight = 112
    UpperLeftX = Int((DisplayWidth-WindowWidth)/2)
    UpperLeftY = Int((DisplayHeight-WindowHeight)/2)

[ControlSetup]
Button      #main.gi, "Get Input",[gi],UL, 245, 45, 105, 25
Button      #main.quit, "Quit",[quit],UL, 365, 45, 105, 25
Textbox     #main.tbox, 15, 10, 455, 24

Open "Demo Window" For Dialog As #main

    Print #main, "trapclose [quit]"
    Print #main, "font ms_sans_serif 10"

[loop]
    Wait

[quit]
    Close #main : End

[gi]
    'This is where I get ready to call my new prompt function.
    'Set Message$ to the prompt string with carriage returns separating
    'lines to be displayed.
    Message$ = "Please enter your name:" + Chr$(13) + _
               "Please enter Last Name First" + _
               Chr$(13) + "Then First Name and Middle Initial"
    'call the fucntion, No title, the message we built above, 3 lines
    'and 10 seconds to timeout.
    promptme$ = GetInput$("", Message$, 3, 10)
    'display the return value in the demo window textbox
    #main.tbox promptme$
    GoTo [loop]


'----------------------------------------------------------------------------
'   Functions, Sub Programs and Data 


Function GetInput$(Title$, Message$, lines, Time)
'-------------------------------------------------------------------
'This function replaces the standard LB PROMPT function with a
'generic, multi-purpose prompt function that returns the user
'input as a string.  It allows multiple lines of prompt text and 
'supports a timed response where the dialog window will close if the
'user has not responded in so many seconds.
'-------------------------------------------------------------------
'By Brad Moore - released to public domain 1/1/2003
'-------------------------------------------------------------------
'Parms:
'Title$ = The title to display on window titlebar
'Message$ = a string containing 1 to 20 lines of text used to prompt
'           the user - separate lines of text with embedded chr$(13)
'lines = The actual number of lines passed (this aids in formatting the 
'        window size and control placement)
'Time = the number of seconds you want to wait before the dialog box
'       times out and closes.  The value 0 (zero) will leave it open
'       an infinite period of time.
'-------------------------------------------------------------------

'Set some defaults if they were not supplied
If Title$ = "" Then Title$ = "User Value Required"
If lines <= 0 Then lines = 1
If lines > 20 Then lines = 20
promptme$ = ""

'Define the dialog box parameters
WindowWidth = 543
WindowHeight = 134 + (lines * 22)
UpperLeftX = Int((DisplayWidth-WindowWidth)/2)
UpperLeftY = Int((DisplayHeight-WindowHeight)/2)

'setup the controls for the window
Statictext  #promptme.static1, Message$, 15, 15, 490, (20 * lines)
If Time > 0 Then
  seconds$ = "Seconds: " + Str$(Time)
  Statictext  #promptme.st2, seconds$, 15, 65 + (20 * lines), 169, 25
End If
Button      #promptme.ok, "OK",[ok.promptme],UL, 265, 65 + (20 * lines), 105, 25
Button      #promptme.cancel, "Cancel",[cancel.promptme],UL, 400, 65 + (20 * lines), 105, 25
Textbox     #promptme.textbox1, 15, 25 + (20 * lines), 490, 25

'open the window
Open Title$ For Dialog_modal As #promptme

'set a trap for close and set the global font
Print #promptme, "trapclose [quit.promptme]"
Print #promptme, "font ms_sans_serif 10"

'If a timed response was desired - turn the timer on
If Time > 0 Then
    counter = Time
    Timer 1000, [update]
End If

'Wait here for a user event
Wait

'Process user events
[ok.promptme]
    'stop the timer
    Timer 0
    'get the contents of the input textbox to be returned
    Print #promptme.textbox1, "!contents? promptme$";
    GoTo [quit.promptme]

[cancel.promptme]
    'stop the timer and set the return string to null
    Timer 0
    promptme$ = ""
    GoTo [quit.promptme]

[update]
     'decrement our second countdown counter
     counter = counter - 1
     'display the new remaining time on the dialog window
     Print #promptme.st2, "Seconds: " + Str$(counter)
     'if there are no more seconds them set then stop the timer
     'set the return string to null and prepare to exit.
     If counter = 0 Then
         Timer 0
         promptme$ = ""
         GoTo [quit.promptme]
     End If
     'if we still have time then just wait here for the next event
     Wait

[quit.promptme]
    'stop the timer, close the prompt window and set the 
    'function return to the value of promptme$
    Timer 0
    Close #promptme
    GetInput$ = promptme$

End Function



Home

Drawn Objects

Documenting Code

Tipcorner - Helpfile

Bmpbuttons

Prompt by Brad Moore

Locate Controls

Tips by Dennis McKinney

Demos by Bill Jennings

Review of TheWrap

Integration by Tom Nally

SQLite by Richard Peeters

Help Writing by Jerry Muelver

Index