1. Structured Programming: QB IS STRUCTURED!!!

>Hi
>
>Ah ha - the goto / gosub/return argument again.
>
>Short answer no - look through the mailing list archives for all the pro 
>and con arguments. Assume there are no subroutines - in the qbasic sense. 
>When you get used to euphoria, its far prettier and easier to read.
>
>As with most things euphoria, there are work arounds
>
>functions - return a value
>procedures - do not return a value
>
>both need to to be found in your program (in the way the program is read), 
>before you actually call them (can use routine_ids, but keep it simple for 
>now)
>
>The 'preferred' method is to only use local variables to your 
>functions/procedured, as this leads to prettier, more re usable code, eg
>
>}}}
<eucode>
>function foo(integer x)
>integer y
>y = x * 2
>return y
>end function
>
>integer z
>z = foo(2)
></eucode>
{{{

>
>now if you used untidy global variables (bad programming practice (hands up 
>those who NEVER do it))
>
>}}}
<eucode>
>integer y, z
>
>procedure foo(integer x)
>y = x * 2
>end procedure
>
>foo(4)
>z = y
></eucode>
{{{

>
>yeuch, horrible.
>
>Is this what you meant.
>
>Also say goodbye to on x gosub/goto, and switch/case statements (are these 
>in qbasic?)
>
>Chris


Tried it.  Didn't work.  Now, since you're so smart, mebbe you can tell me 
if you can find a single goto / gosub / return in this program which is just 
full of subroutines.  And by the way, I insist you read through the whole 
thing.   I have the buggery that prompted this whole mess in the first place 
copied neatly in the code.  Before you ask, yes, it is in the graphics.e 
file.  I looked.  Yes, the include statement is in the beginning of the 
file, before the call to the included file's subroutine.  But I get this 
error.  Mebbe you, who knoweth I do not understandith structured 
programming, could explain to me what the proper structureth be-ith so I can 
codeth in the correcteth structureth?

Your ignorance of the structured nature of QB astounds me.  The only thing 
that could possibly astound me more is the fact that QB - written probably 
close to twenty years ago - parses all the subroutines in to their own 
little windows, so you can edit them individually without having to search 
through the code to find them, and Ed does not.  So much for readability.

Love & Friendship & Blessed Be!
Lynn Erika Kilroy

<!-------------------BEGIN QBASIC SOURCE------------------->
DECLARE SUB ColorLocateInputJustAboutAnything (FGC AS INTEGER, BGC AS 
INTEGER, CTFGC AS INTEGER, CTBGC AS INTEGER, Row AS INTEGER, Col AS INTEGER, 
Text AS STRING, VWidth AS INTEGER)
DECLARE SUB ColorLocatePrint (FGC AS INTEGER, BGC AS INTEGER, Row AS 
INTEGER, Col AS INTEGER, Text AS STRING)
DECLARE SUB EndProgram ()
DECLARE SUB Initialize ()
DECLARE SUB Inkey (a AS STRING)
DECLARE SUB MasterControlProgram ()
DECLARE SUB Prekey (a AS STRING)
DECLARE SUB WaitKey (a AS STRING)

DIM SHARED LastRow AS INTEGER

Initialize
MasterControlProgram
EndProgram

SUB ColorLocateInputJustAboutAnything (FGC AS INTEGER, BGC AS INTEGER, CTFGC 
AS INTEGER, CTBGC AS INTEGER, Row AS INTEGER, Col AS INTEGER, Text AS 
STRING, VWidth AS INTEGER)

: REM FGC = ForeGroundColor
: REM BGC = BackGroundColor
:
: REM CTFGC = CursorTextForeGroundColor
: REM CTFGC = CursorTextBackGroundColor
:
: REM Row = The Row we Print it on
: REM Col = The Column we Print It on
:
: REM Text = The Text We're Editing.  Yes.  Editing.  What'd you think?  
This
: REM        was going to be like INPUT?
:
: REM VWidgth = ViewWidth, in Characters.
:
DIM CursorPosition AS INTEGER
:
DIM VTextStart AS INTEGER
:
DIM InputMode AS STRING
:
DIM a AS STRING

CursorPosition = LEN(a) + 1
VTextStart = CursorPosition - VWidth

InputMode = "OverWrite"

WHILE a <> CHR$(13)

  IF CursorPosition < VTextStart THEN
   VTextStart = CursorPosition
  ELSEIF CursorPosition - VWidth > VTextStart THEN
   VTextStart = CursorPosition - VWidth
  END IF

  IF VTextStart < 1 THEN
   VTextStart = 1
  END IF

  ColorLocatePrint FGC, BGC, Row, Col, SPACE$(VWidth)
  ColorLocatePrint CTFGC, CTBGC, Row, Col + VWidth, MID$(InputMode, 1, 1)
  :
  IF LEN(Text) > VWidth THEN
   ColorLocatePrint FGC, BGC, Row, Col, MID$(Text, VTextStart, VWidth)
  ELSE
   ColorLocatePrint FGC, BGC, Row, Col, Text
  END IF
  :
  ColorLocatePrint CTFGC, CTBGC, Row, Col + CursorPosition - VTextStart, 
MID$(Text + CHR$(176), CursorPosition, 1)

  WaitKey a

  IF LEN(a) = 1 THEN
   :
   IF a = CHR$(8) THEN
    :
    IF CursorPosition > LEN(Text) THEN
     Text = MID$(Text, 1, CursorPosition - 2)
    ELSE
     Text = MID$(Text, 1, CursorPosition - 2) + MID$(Text, CursorPosition, 
LEN(Text) - CursorPostion)
    END IF
    :
    CursorPosition = CursorPosition - 1
    :
   ELSEIF a = CHR$(27) THEN
    :
    Text = ""
    CursorPosition = 1
    :
   ELSEIF a > CHR$(31) THEN
    :
    IF CursorPosition > LEN(Text) THEN
     Text = Text + a
    ELSE
     IF InputMode = "OverWrite" THEN
      MID$(Text, CursorPosition, 1) = a
     ELSEIF InputMode = "Insert" THEN
      Text = MID$(Text, 1, CursorPosition - 1) + a + MID$(Text, 
CursorPosition, LEN(Text) - CursorPosition)
     END IF
    END IF
    :
    CursorPosition = CursorPosition + 1
    :
   ELSEIF a <> CHR$(13) THEN
    :
    BEEP
    :
   END IF
   :
  ELSEIF LEN(a) = 2 THEN
   :
   IF a = CHR$(0) + "G" THEN
    :
    CursorPosition = 1
    :
   ELSEIF a = CHR$(0) + "K" THEN
    :
    CursorPosition = CursorPosition - 1
    :
    IF CursorPosition < 1 THEN
     CursorPosition = 1
     BEEP
    END IF
    :
   ELSEIF a = CHR$(0) + "M" THEN
    :
    CursorPosition = CursorPosition + 1
    :
    IF CursorPosition > LEN(Text) + 1 THEN
     CursorPosition = LEN(Text) + 1
     BEEP
    END IF
    :
   ELSEIF a = CHR$(0) + "O" THEN
    :
    CursorPosition = LEN(Text) + 1
    :
   ELSEIF a = CHR$(0) + "R" THEN
    :
    IF InputMode = "OverWrite" THEN
     InputMode = "Insert"
    ELSE
     InputMode = "OverWrite"
    END IF
    :
   ELSEIF a = CHR$(0) + "S" THEN
    :
    IF CursorPosition > LEN(Text) THEN
     BEEP
    ELSE
     Text = MID$(Text, 1, CursorPosition - 1) + MID$(Text, CursorPosition + 
1, LEN(Text) - CursorPosition)
    END IF
    :
   END IF
  END IF

WEND

END SUB

SUB ColorLocatePrint (FGC AS INTEGER, BGC AS INTEGER, Row AS INTEGER, Col AS 
INTEGER, Text AS STRING)

COLOR FGC, BGC
LOCATE Row, Col
PRINT Text

END SUB

SUB EndProgram

ColorLocatePrint 15, 6, LastRow, 5, "This completes the demonstration 
program I have written to show how QB"
ColorLocatePrint 15, 6, LastRow + 1, 5, "****REALLY**** looks.  If anyone 
sees this and can possibly label it  "
ColorLocatePrint 15, 6, LastRow + 2, 5, "as sloppy or difficult to 
understand or as anything other than modular"
ColorLocatePrint 15, 6, LastRow + 3, 5, "programming in it's purest form, 
then I would love for them to prove  "
ColorLocatePrint 15, 6, LastRow + 4, 5, "it.  In the meantime, don't yell at 
me because you use " + CHR$(34) + "procedure" + CHR$(34) + "    "
ColorLocatePrint 15, 6, LastRow + 5, 5, "where I use " + CHR$(34) + 
"subroutine," + CHR$(34) + " and now know that a function is a function  "
ColorLocatePrint 15, 6, LastRow + 6, 5, "is a function, no matter the 
language.                                "

ColorLocatePrint 15, 6, LastRow + 8, 5, "Now back to my question.  I said 
'include graphics.e.'  Euphoria said "
ColorLocatePrint 15, 6, LastRow + 9, 5, "'O.K.'  I said 'Graphics_Mode 
(260).  Euphoria said 'Graphics_Mode has"
ColorLocatePrint 15, 6, LastRow + 10, 5, "not been declared.'  If I am not 
mistaken, 'Graphics_Mode' is a       "
ColorLocatePrint 15, 6, LastRow + 11, 5, "declared Subroutine in Graphics.E? 
  Or do I need a seperate Declare   "
ColorLocatePrint 15, 6, LastRow + 12, 5, "Procedure statement in the main 
source code?                          "

END SUB

SUB Initialize

WIDTH 80, 50
COLOR 14, 4
CLS

ColorLocatePrint 14, 6, 5, 36, "Welcome!"
ColorLocatePrint 14, 6, 6, 5, "Since you had the nerve to say how poorly 
restrictive QBasic code was "
ColorLocatePrint 14, 6, 7, 5, "writing QBasic Code was, I decided to provide 
this little sample.     "

ColorLocatePrint 15, 6, 9, 5, "Please note that all the information for 
printing these lines is in   "
ColorLocatePrint 15, 6, 10, 5, "ONE statement.  Now we will have you enter 
some text, and print it out"
ColorLocatePrint 15, 6, 11, 5, "for you to read.                             
                          "

ColorLocatePrint 15, 6, 14, 5, "Ready?                                       
                          "

ColorLocatePrint 15, 6, 16, 5, "Begin.                                       
                          "


END SUB

SUB Inkey (a AS STRING)

a = INKEY$

END SUB

SUB MasterControlProgram

DIM a AS STRING
DIM b AS INTEGER
DIM c AS STRING

ColorLocateInputJustAboutAnything 15, 6, 0, 7, 18, 5, a, 70

ColorLocatePrint 15, 6, 20, 5, "I will now attempt to parse your input.      
                          "

LastRow = 22

WHILE LastRow < 41 AND LEN(a) > 70

  b = 71

  WHILE b > 1 AND MID$(a, b, 1) <> " "
   b = b - 1
  WEND

  IF MID$(a, b, 1) = " " THEN
   c = MID$(a, 1, b - 1)
   ColorLocatePrint 14, 6, LastRow, 5, c + SPACE$(70 - LEN(c))
   a = MID$(a, b + 1, LEN(a) - b)
  ELSE
   a = "Truncated: " + a
   ColorLocatePrint 14, 6, LastRow, 5, MID$(a, 1, 70)
   a = MID$(a, 71, LEN(a) - 70)
  END IF

  LastRow = LastRow + 1
  :
  IF LastRow = 31 THEN
   IF LEN(a) > 0 THEN
    a = "***Too Many Lines To Display!***"
   END IF
  END IF

WEND

IF LEN(a) > 0 THEN
  ColorLocatePrint 14, 6, LastRow, 5, a + SPACE$(70 - LEN(a))
END IF

LastRow = LastRow + 2

END SUB

SUB Prekey (a AS STRING)

a = " "

WHILE a > ""
  Inkey a
WEND

END SUB

SUB WaitKey (a AS STRING)

Prekey a

WHILE a = ""
  Inkey a
WEND

END SUB

new topic     » topic index » view message » categorize

2. Re: Structured Programming: QB IS STRUCTURED!!!

Lynn Kilroy wrote:
> 
> >Hi
> >
> >Ah ha - the goto / gosub/return argument again.
> >
> >Short answer no - look through the mailing list archives for all the pro 
> >and con arguments. Assume there are no subroutines - in the qbasic sense. 
> >When you get used to euphoria, its far prettier and easier to read.
> >
> >As with most things euphoria, there are work arounds
> >
> >functions - return a value
> >procedures - do not return a value
> >
> >both need to to be found in your program (in the way the program is read), 
> >before you actually call them (can use routine_ids, but keep it simple for 
> >now)
> >
> >The 'preferred' method is to only use local variables to your 
> >functions/procedured, as this leads to prettier, more re usable code, eg
> >
> >}}}
<eucode>
> >function foo(integer x)
> >integer y
> >y = x * 2
> >return y
> >end function
> >
> >integer z
> >z = foo(2)
> ></eucode>
{{{

> >
> >now if you used untidy global variables (bad programming practice (hands up 
> >those who NEVER do it))
> >
> >}}}
<eucode>
> >integer y, z
> >
> >procedure foo(integer x)
> >y = x * 2
> >end procedure
> >
> >foo(4)
> >z = y
> ></eucode>
{{{

> >
> >yeuch, horrible.
> >
> >Is this what you meant.
> >
> >Also say goodbye to on x gosub/goto, and switch/case statements (are these 
> >in qbasic?)
> >
> >Chris
> 
> 
> Tried it.  Didn't work.  Now, since you're so smart, mebbe you can tell me 
> if you can find a single goto / gosub / return in this program which is just

Whoa - this is setting the tone.
> 
> full of subroutines.  And by the way, I insist you read through the whole 
> thing.   I have the buggery that prompted this whole mess in the first place
> 
> copied neatly in the code.  Before you ask, yes, it is in the graphics.e 
> file.  I looked.  Yes, the include statement is in the beginning of the 
> file, before the call to the included file's subroutine.  But I get this 
> error.  Mebbe you, who knoweth I do not understandith structured 
> programming, could explain to me what the proper structureth be-ith so I can
> 
> codeth in the correcteth structureth?
> 
> Your ignorance of the structured nature of QB astounds me.  

Why? I haven't used QBASIC for 20 years. So much for trying to help poeple. Why
bother.

The only thing 
> that could possibly astound me more is the fact that QB - written probably 
> close to twenty years ago - parses all the subroutines in to their own 
> little windows, so you can edit them individually without having to search 
> through the code to find them, and Ed does not.  So much for readability.
> 
> Love & Friendship & Blessed Be!

Thats an oxymoron isn't it.


> Lynn Erika Kilroy
> 
> <!-------------------BEGIN QBASIC SOURCE------------------->
> DECLARE SUB ColorLocateInputJustAboutAnything (FGC AS INTEGER, BGC AS 
> INTEGER, CTFGC AS INTEGER, CTBGC AS INTEGER, Row AS INTEGER, Col AS INTEGER,
> 
> Text AS STRING, VWidth AS INTEGER)
> DECLARE SUB ColorLocatePrint (FGC AS INTEGER, BGC AS INTEGER, Row AS 
> INTEGER, Col AS INTEGER, Text AS STRING)
> DECLARE SUB EndProgram ()
> DECLARE SUB Initialize ()
> DECLARE SUB Inkey (a AS STRING)
> DECLARE SUB MasterControlProgram ()
> DECLARE SUB Prekey (a AS STRING)
> DECLARE SUB WaitKey (a AS STRING)
> 
> DIM SHARED LastRow AS INTEGER
> 
> Initialize
> MasterControlProgram
> EndProgram
> 
> SUB ColorLocateInputJustAboutAnything (FGC AS INTEGER, BGC AS INTEGER, CTFGC
> 
> AS INTEGER, CTBGC AS INTEGER, Row AS INTEGER, Col AS INTEGER, Text AS 
> STRING, VWidth AS INTEGER)
> 
> : REM FGC = ForeGroundColor
> : REM BGC = BackGroundColor
> :
> : REM CTFGC = CursorTextForeGroundColor
> : REM CTFGC = CursorTextBackGroundColor
> :
> : REM Row = The Row we Print it on
> : REM Col = The Column we Print It on
> :
> : REM Text = The Text We're Editing.  Yes.  Editing.  What'd you think?  
> This
> : REM        was going to be like INPUT?
> :
> : REM VWidgth = ViewWidth, in Characters.
> :
> DIM CursorPosition AS INTEGER
> :
> DIM VTextStart AS INTEGER
> :
> DIM InputMode AS STRING
> :
> DIM a AS STRING
> 
> CursorPosition = LEN(a) + 1
> VTextStart = CursorPosition - VWidth
> 
> InputMode = "OverWrite"
> 
> WHILE a <> CHR$(13)
> 
>   IF CursorPosition < VTextStart THEN
>    VTextStart = CursorPosition
>   ELSEIF CursorPosition - VWidth > VTextStart THEN
>    VTextStart = CursorPosition - VWidth
>   END IF
> 
>   IF VTextStart < 1 THEN
>    VTextStart = 1
>   END IF
> 
>   ColorLocatePrint FGC, BGC, Row, Col, SPACE$(VWidth)
>   ColorLocatePrint CTFGC, CTBGC, Row, Col + VWidth, MID$(InputMode, 1, 1)
>   :
>   IF LEN(Text) > VWidth THEN
>    ColorLocatePrint FGC, BGC, Row, Col, MID$(Text, VTextStart, VWidth)
>   ELSE
>    ColorLocatePrint FGC, BGC, Row, Col, Text
>   END IF
>   :
>   ColorLocatePrint CTFGC, CTBGC, Row, Col + CursorPosition - VTextStart, 
> MID$(Text + CHR$(176), CursorPosition, 1)
> 
>   WaitKey a
> 
>   IF LEN(a) = 1 THEN
>    :
>    IF a = CHR$(8) THEN
>     :
>     IF CursorPosition > LEN(Text) THEN
>      Text = MID$(Text, 1, CursorPosition - 2)
>     ELSE
>      Text = MID$(Text, 1, CursorPosition - 2) + MID$(Text, CursorPosition,
> 
> LEN(Text) - CursorPostion)
>     END IF
>     :
>     CursorPosition = CursorPosition - 1
>     :
>    ELSEIF a = CHR$(27) THEN
>     :
>     Text = ""
>     CursorPosition = 1
>     :
>    ELSEIF a > CHR$(31) THEN
>     :
>     IF CursorPosition > LEN(Text) THEN
>      Text = Text + a
>     ELSE
>      IF InputMode = "OverWrite" THEN
>       MID$(Text, CursorPosition, 1) = a
>      ELSEIF InputMode = "Insert" THEN
>       Text = MID$(Text, 1, CursorPosition - 1) + a + MID$(Text, 
> CursorPosition, LEN(Text) - CursorPosition)
>      END IF
>     END IF
>     :
>     CursorPosition = CursorPosition + 1
>     :
>    ELSEIF a <> CHR$(13) THEN
>     :
>     BEEP
>     :
>    END IF
<snip>


http://members.aol.com/chriscrylex/euphoria.htm
http://uboard.proboards32.com/
http://members.aol.com/chriscrylex/EUSQLite/eusql.html

new topic     » goto parent     » topic index » view message » categorize

3. Re: Structured Programming: QB IS STRUCTURED!!!

Chris Burch wrote:

> Why? I haven't used QBASIC for 20 years.

There you go. smile

I'm comfused at why Lynn would be using such old programming technology in 2006!
I mean considering that there is a newer generation of Visual Basic and .NET
tools offered by Microsoft. Qbasic has not been supported for a good decade I
think, and is virtually dead today. In fact, the operating system it was designed
to run on is also dead. We have a buggy emulation of it now (if that) which is
only suitable for toying around, running ancient software, or developing batch
file scripts.

If Lynn went into a chatroom with discussion about modern programming, they'd
quickly laugh when they discover how enthusatstic Lynn is about ancient Qbasic!

No affense Lynn.


Regards,
Vincent

new topic     » goto parent     » topic index » view message » categorize

4. Re: Structured Programming: QB IS STRUCTURED!!!

Vincent wrote:
> 
> Chris Burch wrote:
> 
> > Why? I haven't used QBASIC for 20 years.
> 
> There you go. smile
> 
> I'm comfused at why Lynn would be using such old programming technology in
> 2006!
> I mean considering that there is a newer generation of Visual Basic and .NET
> tools offered by Microsoft. Qbasic has not been supported for a good decade
> I think, and is virtually dead today. In fact, the operating system it was
> designed
> to run on is also dead. We have a buggy emulation of it now (if that) which
> is only suitable for toying around, running ancient software, or developing
> batch file scripts.
> 
> If Lynn went into a chatroom with discussion about modern programming, they'd
> quickly laugh when they discover how enthusatstic Lynn is about ancient
> Qbasic!
> 
> No affense Lynn.
> 
> 
> Regards,
> Vincent

Although I've never used it, I think a lot of people still use QBasic.

A lot of people still program for DOS, Win98 and earlier, and other "older"
technologies.

Just because something new is released doesn't make all the old stuff suddenly
stop working!

Plus, you can get QBasic for free. I don't think you can get Visual Basic for
free.

--
"Actually, I'm sitting on my butt staring at a computer screen."
                                                  - Tom Tomorrow

j.

new topic     » goto parent     » topic index » view message » categorize

5. Re: Structured Programming: QB IS STRUCTURED!!!

Copy, paste and run

-- Extremely Simple Text-mode Dialogs --
----------------------------------------

modified to be dual platform CM Burch (29/12/04)

still to do - get Linux to display properly some forms entry anomalies

from the original by Irv Mullins and D. Cuny

include graphics.e color names include dll.e include wildcard.e include misc.e include get.e

without warning

constant COLORS = 1, FGND = 1, BKGND = 2, box structure COORDS = 2, ROW = 1, COL = 2, SIZE = 3, HEIGHT = 1, WIDTH = 2, MINH = 4, MINW = 8, STYLE = 4, SHADOW = 5, HINT = 6, HINTCOLORS = 7, BUFFER = 8

global integer SGL, DBL, DHL, DVL, NONE, up, dn, left, right, ENTER, ESC, SP, pgup, pgdn, home, endd, insert, bksp, del, tab, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12

global sequence Lines, Divider, Shadow global integer TL, HL, TR, VL, BL, BR global sequence ENV ENV = "Windows"

tab = '\t' TL = 1 HL = 2 TR = 3 VL = 4 BL = 5 BR = 6

if platform() = LINUX then SGL = 1 DBL = 2 DHL = 3 DVL = 4 NONE = 5 border styles

key defines up = 259 dn = 258 left = 260 right = 261 ENTER = 10 ESC = 27 SP = 32 pgup = 339 pgdn = 338 home = 262 endd = 360 insert = 331 bksp = 263 del = 330 F1 = 265 F2 = 266 F3 = 267 F4 = 268 F5 = 269 F6 = 270 F7 = 271 F8 = 272 F9 = 273 F10 = 274 F11 = 275 F12 = 276

these have been changed from the 'graphic' character set Lines = {{'+','-','+','|','+','+'}, single line borders {'+','-','+','|','+','+'}, double line borders {'+','-','+','|','+','+'}, double horizontal {'+','-','+','|','+','+'}, double vertical {' ',' ',' ',' ',' ',' '} } none

Divider = {{'+','-','+'}, single style divider line {'+','-','+'}, {'+','-','+'}, double horizontal {'+','-','+'}, {' ',' ',' '}}

Shadow = {' ',' ',' '} 3 different shadow backgrounds

ENV = getenv("TERM") if match(upper(ENV), "XTERM") = -10 then set to -10 to ignore it for now

xterms seem to work differently - try Windows set Lines = {{218,196,191,179,192,217}, single line borders {201,205,187,186,200,188}, double line borders {213,205,184,179,212,190}, double horizontal {214,196,183,186,211,189}, double vertical {' ',' ',' ',' ',' ',' '}} none

Divider = {{195,196,180}, single style divider line {204,205,185}, {198,205,181}, double horizontal {199,196,182}, {' ',' ',' '}}

Shadow = {176,177,178} 3 different shadow backgrounds end if

else SGL = 1 DBL = 2 DHL = 3 DVL = 4 NONE = 5 border styles

key defines wim32 / dos up = 328 dn = 336 left = 331 right = 333 ENTER = 13 ESC = 27 SP = 32 pgup = 329 pgdn = 337 home = 327 endd = 335 insert = 338 bksp = 8 del = 339 F1 = 315 F12 = 316 F3 = 317 F4 = 318 F5 = 319 F6 = 320 F7 = 321 F8 = 322 F9 = 323 F10 = 324 F11 = 325 F12 = 326

have to work out codes for lines

Lines = {{'?,'?,'¿','³','?,'?}, single line borders

{'?,'?,'»','º','?,'¼'}, double line borders

{'?,'?,'¸','³','?,'¾'}, double horizontal

{'?,'?,'·','º','?,'½'}, double vertical

{' ',' ',' ',' ',' ',' '}} none

Divider = {{'?,'?,'´'}, single style divider line {'?,'?,'¹'},

{'?,'?,'µ'}, double horizontal

{'?,'?,'¶'}, {' ',' ',' '}}

Shadow = {'°','±','²'} 3 different shadow backgrounds Lines = {{218,196,191,179,192,217}, single line borders {201,205,187,186,200,188}, double line borders {213,205,184,179,212,190}, double horizontal {214,196,183,186,211,189}, double vertical {' ',' ',' ',' ',' ',' '}} none

Divider = {{195,196,180}, single style divider line {204,205,185}, {198,205,181}, double horizontal {199,196,182}, {' ',' ',' '}}

Shadow = {176,177,178} 3 different shadow backgrounds

end if

global atom SCREEN_BKGND SCREEN_BKGND = BLACK

global atom LIST_KEY

global sequence DefaultBox DefaultBox = {{BRIGHT_WHITE,BLUE}, default colors {1,1}, coordinates top left corner {5,10}, box size SGL, single line border 1, light shadow "Press any key...", hint text {GREEN,BLACK}, hint colors {}} buffer for save screen

to accomodate usage in xterm or konsole that hasn't been set to 25 lines

if you know it has, then set it to 25, to appear at bottom of screen global integer SCREEN_LINES, SCREEN_COLS SCREEN_LINES = 24 SCREEN_COLS = 80 global sequence vid_conf


vid_conf = video_config() SCREEN_LINES = vid_conf[VC_LINES] SCREEN_COLS = vid_conf[VC_COLUMNS]


global procedure printat(sequence coords, sequence text)


position(coords[1],coords[2]) puts(1,text) end procedure


global procedure printcolor(sequence coords, sequence colors, sequence text)


text_color(colors[1]) bk_color(colors[2]) printat(coords,text) end procedure


global function limit (atom n, sequence limits)


if n < limits[1] then n = limits[1] elsif n > limits[2] then n = limits[2] end if return n end function


global function pad (sequence s, atom width)


while length(s) < width do s = s & ' ' end while return s end function


global function delete (sequence s, atom loc, atom len)


return s[1..loc-1] & s[loc+len..length(s)] end function


global function Fdialogs_rts(sequence str) remove trailng spaces
integer x

x = length(str) if x = 0 then return "" end if

while str[x] = 32 or str[x] = '\n' or str[x] = 0 or str[x] = '\t' do x = x-1 if x <= 1 then exit end if end while

if x < 1 then x = 1 end if str = str[1..x]

if length(str) = 1 and (str[1] = 32 or str[1] = ENTER) then str = "" end if

return str end function


procedure MoveCursor(sequence coords)


position(coords[ROW],coords[COL]) end procedure


function SaveBkgnd(object box)


cursor(NO_CURSOR) box[COORDS] = get_position() box[BUFFER] = save_text_image(box[COORDS],box[COORDS]+box[SIZE]+2) cursor(UNDERLINE_CURSOR) return box end function


global procedure RestoreBkgnd(object box)


MoveCursor(box[COORDS]) display_text_image(box[COORDS],box[BUFFER]) end procedure
< BOX >---------------------------------

see the global defs at the top for characters for boxes.


global function PlainBox(sequence box) almost the same as display box, but no title area
sequence topline, botline, midline, divline, rshad, bshad, char atom row, col, x, y box = SaveBkgnd(box) row = box[COORDS][ROW] col = box[COORDS][COL] x = box[SIZE][WIDTH] y = box[SIZE][HEIGHT] text_color(box[COLORS][FGND]) bk_color(box[COLORS][BKGND]) cursor(NO_CURSOR)

grab the area to be shadowed:

rshad = save_text_image({row+1,col+x+2},{row+y+1,col+x+2}) bshad = save_text_image({row+y+1,col+1},{row+y+1,col+x+1})

select the border style to use: char = Lines[box[STYLE]]

build the borders: topline = char[TL] & repeat(char[HL],x) & char[TR] botline = char[BL] & repeat(char[HL],x) & char[BR] midline = char[VL] & repeat(' ',x) & char[VL] char = Divider[box[STYLE]] divline = char[1] & repeat(char[2],x) & char[3]

draw the borders: printat({row,col}, topline) for i = 1 to y do printat({row+i,col}, midline) end for

printat({row + 2,col}, divline) printat({row + y,col}, botline)

MoveCursor(box[COORDS]) restore cursor to start cursor(UNDERLINE_CURSOR) return box

end function


global function DisplayBox(sequence box)


sequence topline, botline, midline, divline, rshad, bshad, char atom row, col, x, y box = SaveBkgnd(box) row = box[COORDS][ROW] col = box[COORDS][COL] x = box[SIZE][WIDTH] y = box[SIZE][HEIGHT] text_color(box[COLORS][FGND]) bk_color(box[COLORS][BKGND]) cursor(NO_CURSOR)

grab the area to be shadowed:

rshad = save_text_image({row+1,col+x+2},{row+y+1,col+x+2}) bshad = save_text_image({row+y+1,col+1},{row+y+1,col+x+1})

select the border style to use: char = Lines[box[STYLE]]

build the borders: topline = char[TL] & repeat(char[HL],x) & char[TR] botline = char[BL] & repeat(char[HL],x) & char[BR] midline = char[VL] & repeat(' ',x) & char[VL] char = Divider[box[STYLE]] divline = char[1] & repeat(char[2],x) & char[3]

draw the borders: printat({row,col}, topline) for i = 1 to y do printat({row+i,col}, midline) end for printat({row + 2,col}, divline) printat({row + y,col}, botline)

draw the shadows:

if box[SHADOW] > 0 then position(20,1)

for i = 1 to length(rshad) do rshad[i][2] = rshad[i][2] / 16

rshad[i][1] = Shadow[box[SHADOW]] end for

for i = 2 to length(bshad[1]) by 2 do bshad[1][i] = bshad[1][i] / 16

bshad[1][i-1] = Shadow[box[SHADOW]] end for

display_text_image({row+1,col+x+2},rshad) display_text_image({row+y+1,col+1},bshad)

end if

MoveCursor(box[COORDS]) restore cursor to start cursor(UNDERLINE_CURSOR) return box end function


global procedure SetColors(atom fgnd, atom bkgnd)


DefaultBox[COLORS] = {fgnd,bkgnd} end procedure


global procedure SetSize(atom rows, atom cols)


DefaultBox[SIZE] = {rows,cols} end procedure


global procedure SetStyle(atom style)


DefaultBox[STYLE] = style end procedure


global procedure SetHint(sequence hint)


DefaultBox[HINT] = hint end procedure


global procedure DisplayHint(sequence hint)


printcolor({SCREEN_LINES,2},DefaultBox[HINTCOLORS],repeat(' ',78)) printcolor({SCREEN_LINES,3},DefaultBox[HINTCOLORS],hint) end procedure


procedure DisplayList(sequence coords, sequence colors, sequence list, atom default)


for i = 1 to length(list) do if i = default then printcolor(coords+{i,0},{colors[2],colors[1]},list[i]) else printcolor(coords+{i,0},colors,list[i]) end if end for end procedure


global function GenericBox (sequence title, sequence msg)


object msgbox msgbox = DefaultBox copy defaults if length(title) > 0 then msgbox = DisplayBox(msgbox) printat(msgbox[COORDS]+{1,1},title) DisplayList(msgbox[COORDS]+{2,1},msgbox[COLORS],msg,0) else msgbox = PlainBox(msgbox) DisplayList(msgbox[COORDS] + {0,1},msgbox[COLORS],msg,0) end if return msgbox end function


global procedure MessageBox (sequence title, sequence msg)


object box box = GenericBox(title,msg) end procedure


global procedure Notify (sequence title, sequence msg)


object box box = GenericBox(title,msg) DisplayHint( "Press any key...") while get_key() = -1 do wait for keypress end while RestoreBkgnd(box) end procedure


global function Select (sequence title, atom default, sequence items) set title to "" for no title

not working yet - always use a title atm


object box, hilite atom key, selection integer offset

offset = 0 if length(title) > 0 then offset = 2 else offset = 0 end if

box = GenericBox(title,items) DisplayHint( "Select with up/dn arrows - press enter - esc to cancel" ) key = -1 selection = default cursor(NO_CURSOR)

DisplayList(box[COORDS]+{offset,1},box[COLORS],items,selection) while key != ENTER do key = upper(get_key()) if key >= 'A' and key <= 'Z' then for i = selection to length(items) do if items[i][1] = key then selection = i exit end if end for end if

if key = up then selection = limit(selection - 1,{1,length(items)}) elsif key = dn then selection = limit(selection + 1,{1,length(items)}) elsif key = pgup then selection = 1 elsif key = pgdn then selection = length(items) elsif key = left then key = 27 elsif key = right then key = 13 elsif key = ESC then selection = -1 exit end if if key != -1 then DisplayList(box[COORDS]+{offset,1},box[COLORS],items,selection) end if end while RestoreBkgnd(box) cursor(UNDERLINE_CURSOR) return selection end function


global function CheckBox(sequence title, sequence items)


object box, selecteditems atom key, selection for i = 1 to length(items) do items[i] = "[ ] "&items[i] end for box = GenericBox(title,items) DisplayHint("Select with up/dn arrows, toggle with spacebar, enter when finished") key = -1 selection = 1 MoveCursor(box[COORDS]+{selection+2,2}) while key != 13 do key = get_key() if key != -1 then MoveCursor(box[COORDS]+{selection+2,2}) end if if key = SP then if items[selection][2] = 'X' then items[selection][2] = ' ' else items[selection][2] = 'X' end if printcolor(box[COORDS]+{selection+2,1},box[COLORS],items[selection]) MoveCursor(box[COORDS]+{selection+2,2}) elsif key = up then selection = limit(selection - 1,{1,length(items)}) MoveCursor(box[COORDS]+{selection+2,2}) elsif key = dn then selection = limit(selection + 1,{1,length(items)}) MoveCursor(box[COORDS]+{selection+2,2}) elsif key = ENTER then exit end if end while selecteditems = {} for i = 1 to length(items) do if items[i][2] = 'X' then selecteditems = append(selecteditems,items[i][5..length(items[i])]) end if end for return selecteditems end function


global function RadioBox(sequence title, sequence items)


object box, selecteditems atom key, selection for i = 1 to length(items) do items[i] = "( ) "&items[i] end for box = GenericBox(title,items) DisplayHint("Select with up/dn arrows, toggle with spacebar, enter when finished") key = -1 selection = 1 MoveCursor(box[COORDS]+{selection+2,2}) while key != 13 do key = get_key() if key = SP then if items[selection][2] = 'X' then items[selection][2] = ' ' else items[selection][2] = 'X' printcolor(box[COORDS]+{selection+2,1},box[COLORS],items[selection]) end if for i = 1 to length(items) do if i != selection then items[i][2] = ' ' reset all buttons printcolor(box[COORDS]+{i+2,1},box[COLORS],items[i]) end if end for printat(box[COORDS]+{selection+2,1},items[selection]) MoveCursor(box[COORDS]+{selection+2,2}) elsif key = up then selection = limit(selection - 1,{1,length(items)}) MoveCursor(box[COORDS]+{selection+2,2}) elsif key = dn then selection = limit(selection + 1,{1,length(items)}) MoveCursor(box[COORDS]+{selection+2,2}) elsif key = ENTER or key = ESC then exit end if end while selecteditems = {} for i = 1 to length(items) do if items[i][2] = 'X' then selecteditems = append(selecteditems,items[i][5..length(items[i])]) end if end for return selecteditems end function


global function RadioBox_def(sequence title, sequence items, integer def) same as RadioBox, except takes a third parameter which defines the

preset selection


object box, selecteditems atom key, selection

if def > length(items) then def = 1 end if

for i = 1 to length(items) do if def != i then items[i] = "( ) "&items[i] else items[i] = "(X) "&items[i] end if end for box = GenericBox(title,items) DisplayHint("Select with up/dn arrows, toggle with spacebar, enter when finished") key = -1 selection = 1 MoveCursor(box[COORDS]+{selection+2,2}) while key != 13 do key = get_key() if key = SP then if items[selection][2] = 'X' then items[selection][2] = ' ' else items[selection][2] = 'X' printcolor(box[COORDS]+{selection+2,1},box[COLORS],items[selection]) end if for i = 1 to length(items) do if i != selection then items[i][2] = ' ' reset all buttons printcolor(box[COORDS]+{i+2,1},box[COLORS],items[i]) end if end for printat(box[COORDS]+{selection+2,1},items[selection]) MoveCursor(box[COORDS]+{selection+2,2}) elsif key = up then selection = limit(selection - 1,{1,length(items)}) MoveCursor(box[COORDS]+{selection+2,2}) elsif key = dn then selection = limit(selection + 1,{1,length(items)}) MoveCursor(box[COORDS]+{selection+2,2}) elsif key = ENTER or key = ESC then exit end if end while selecteditems = {} for i = 1 to length(items) do if items[i][2] = 'X' then selecteditems = append(selecteditems,items[i][5..length(items[i])]) end if end for return selecteditems end function


global function ListBox(sequence title, sequence items, atom start)


object box atom key, current, fini, max, itemcount box = GenericBox(title,"") key = -1 current = 1 itemcount = length(items) max = box[SIZE][1] - 3 for i = 1 to itemcount do items[i] = pad(items[i],box[SIZE][2]) end for fini = itemcount fini = limit(fini,{1,itemcount}) fini = limit(fini,{fini,max}) cursor(NO_CURSOR) DisplayList(box[COORDS]+{2,1},box[COLORS],items[start..fini],start) while key != 27 do key = get_key() if key = ESC then exit elsif key = ENTER then exit elsif key = up then current = limit(current - 1,{1,itemcount}) if current < start then start = limit(start - 1,{1,itemcount}) fini = start + max - 1 end if DisplayList(box[COORDS]+{2,1},box[COLORS],items[start..fini],current-start+1)

elsif key = dn then current = limit(current + 1,{1,itemcount}) if current > fini then fini = limit(fini + 1,{1,itemcount}) start = fini - max + 1 end if DisplayList(box[COORDS]+{2,1},box[COLORS],items[start..fini],current-start+1) end if end while cursor(UNDERLINE_CURSOR) return items[current] end function


Same as list box, but returns index, not selected item global function ListBoxIndex(sequence title, sequence items, atom selected)

set the title length to 0 ( "" ) to create a titless list box


object box atom key, current, fini, max, itemcount,start, list_start_pos this is the start position of the list in the box integer cur_sel box = GenericBox(title,"") key = -1 current = 1 cur_sel = 1 start = 1

if length(title) > 0 then list_start_pos = 2 else list_start_pos = 0 end if

itemcount = length(items) max = box[SIZE][1] - (1 + list_start_pos) sets max size of list for i = 1 to itemcount do items[i] = pad(items[i],box[SIZE][2]) end for fini = itemcount fini = limit(fini,{1,itemcount}) fini = limit(fini,{fini,max}) cursor(NO_CURSOR)

simulate key down until get to selected item if selected <= itemcount then while current != selected do current = limit(current + 1,{1,itemcount}) cur_sel = current if current > fini then fini = limit(fini + 1,{1,itemcount}) start = fini - max + 1 end if end while end if

DisplayList(box[COORDS]+{2,1},box[COLORS],items[start..fini],start) DisplayList(box[COORDS]+{list_start_pos,1},box[COLORS],items[start..fini],current-start+1) while key != 27 do LIST_KEY = 0 key = get_key() if key = ESC then cur_sel = -1 exit elsif key = ENTER or key = left or key = right then LIST_KEY = key exit elsif key = up then current = limit(current - 1,{1,itemcount}) cur_sel = current if current < start then start = limit(start - 1,{1,itemcount}) fini = start + max - 1 end if DisplayList(box[COORDS]+{list_start_pos,1},box[COLORS],items[start..fini],current-start+1)

elsif key = dn then current = limit(current + 1,{1,itemcount}) cur_sel = current if current > fini then fini = limit(fini + 1,{1,itemcount}) start = fini - max + 1 end if DisplayList(box[COORDS]+{list_start_pos,1},box[COLORS],items[start..fini],current-start+1)

elsif key > 31 and key <129 then LIST_KEY = key exit end if end while cursor(UNDERLINE_CURSOR)

return cur_sel end function


global function Input (sequence title, sequence prompt, sequence default)


sequence result, pcoords, icoords, box atom key,i,imax, imode, max box = GenericBox(title,prompt) pcoords = get_position() icoords = pcoords max = length(default) printcolor(icoords,{box[COLORS][2],box[COLORS][1]},default) DisplayHint("Edit this field, press enter when done, or ESC to cancel") MoveCursor(icoords) result = default key = -1 i = 0 imax = length(default) imode = 0 while key != 13 do key = get_key() if key != -1 then if key = ENTER then exit elsif key = ESC then result = default exit elsif key = bksp then backspace if i > 0 then result = delete(result,i,1) & ' ' printat(icoords,result) imax = length(result) i = i - 1 end if elsif key = left then i = limit(i-1,{0,max}) left arrow elsif key = right then i = limit(i+1,{0,max}) right arrow elsif key = home then i = 0 home elsif key = endd then i = max-1 end elsif key = insert then INS key imode = not(imode) toggle insert mode if imode = 1 then cursor(BLOCK_CURSOR) else cursor(UNDERLINE_CURSOR) end if elsif key > 31 and key < 129 then

if imode then i = limit(i+1,{1,max}) result[i] = key else result = result[1..i] & key & result[i+1..length(result)] result = result[1..max] i = limit(i+1,{1,max}) end if end if printcolor(icoords,{box[COLORS][2],box[COLORS][1]},result) position(icoords[1],icoords[2]+i) end if end while RestoreBkgnd(box) return result end function


global procedure Progress(sequence title, sequence msg, atom percent)


object box, pbar box = GenericBox(title,{msg}) pbar = repeat(' ',box[SIZE][COL] - 4) MoveCursor(box[COORDS]+{5,2}) puts(1,pbar) pbar = repeat('#',length(pbar) * percent * .01) MoveCursor(box[COORDS]+{5,2}) puts(1,pbar) end procedure


global procedure Delay(atom sec)


object start, fini start = time() fini = start + sec while time() < fini do end while end procedure

global integer WORD_WRAP WORD_WRAP = 0


function wrap_fields(sequence field_buffers, integer current_field, object overflow)


sequence lfb, temp_word integer posn_in_field

lfb = repeat({}, length(field_buffers) ) posn_in_field = 0

record the length of each of the field_buffers for i = 1 to length(field_buffers) do lfb[i] = length(field_buffers[i]) end for

make sure overflow is a sequence if atom(overflow) then overflow = {overflow} end if

work forwards from current_field to end for i = current_field to length(field_buffers) do

work backwards from end of current_field to space for j = lfb[i] to 1 by -1 do if field_buffers[i][j] = ' ' then posn_in_field = j if j < lfb[i] then overflow = append(field_buffers[i][j+1..$], overflow) overflow = field_buffers[i][j+1..$] & overflow end if

thats got the overflow, now clear that last word for k = j to lfb[i] do field_buffers[i][k] = ' ' end for exit end if end for

overflow = Fdialogs_rts(overflow) if length(overflow) = 0 then exit else if i < length(field_buffers) then field_buffers[i+1] = overflow & " " & field_buffers[i+1] append(overflow, field_buffers[i+1]) overflow = field_buffers[i+1][ lfb[i+1]+1 ..$ ] field_buffers[i+1] = field_buffers[i+1][1..lfb[i+1]] end if overflow = Fdialogs_rts(overflow) if length(overflow) = 0 then exit end if

end if

end for

return field_buffers end function


global function Form(sequence title, sequence fields) fields - label, default, field size
sequence field_buffers, labels, str sequence result, box, field_coords, pcoords, input_field integer j, lines, field_count, size_x, size_y, start_field integer max_field_length, current_field, curs_posn, offset, ready_to_wrap, have_wrapped atom key, cur_style, field_change, imode object overflow

pcoords = get_position()

str = {} overflow = 0 have_wrapped = 0

calculate number of lines (1 line = 1 label + 1 field) field_count = length(fields) lines = field_count/3

find max_field_length max_field_length = 0 for i = 3 to field_count by 3 do if fields[i] > max_field_length then max_field_length = fields[i] end if end for

set box size if length(title) > 0 then size_x = lines+3 offset = 3 else size_x = lines+1 offset = 1 end if

size_y = length(fields[1]) + length(fields[2]) + 4 1st 2 fields set width of box - all other fields should be same size size_y = length(fields[1]) + max_field_length + 4 start_field = length(fields[1]) + 2 SetSize(size_x, size_y)

create field_buffers field_buffers = repeat({}, lines) for i = 1 to length(field_buffers) do field_buffers[i] = repeat(' ', fields[i*3]) end for

fill in any defaults for i = 1 to lines do if length(fields[((i-1)*3)+2]) > 0 then for k = 1 to length(fields[((i-1)*3)+2]) do if k > length(field_buffers[i]) then exit end if field_buffers[i][k] = fields[((i-1)*3)+2][k] end for end if end for

create labels labels = repeat({}, lines) for i = 1 to lines do labels[i] = fields[((i-1)*3)+1] end for

create box box = GenericBox(title, {})

for i = 1 to lines do printcolor(box[COORDS]+{offset+i-1, 1}, {box[COLORS][1], box[COLORS][2]},labels[i]) printcolor(box[COORDS]+{offset+i-1, 1+start_field}, {WHITE, BLACK}, field_buffers[i]) end for

input loop key = 0 current_field = 1 curs_posn = 1 imode = 1 if WORD_WRAP = 1 then printcolor(box[COORDS]+{offset+lines, 1}, {WHITE, BLACK}, "ovr") end if print current field printcolor(box[COORDS]+{offset+current_field-1, 1+start_field}, {WHITE, BLACK}, field_buffers[current_field]) position(box[COORDS][1] + offset+current_field-1, box[COORDS][2] + curs_posn+start_field) cursor(UNDERLINE_CURSOR)

while key != ESC do key = get_key() if key > 0 then

if key = right then curs_posn += 1 if curs_posn > length(field_buffers[current_field]) then curs_posn -= 1 end if elsif key = left then curs_posn -= 1 if curs_posn < 1 then curs_posn = 1 end if elsif key = up then current_field -= 1 if current_field < 1 then current_field = 1 end if if curs_posn > length(field_buffers[current_field]) then curs_posn = 1 end if elsif key = dn then current_field += 1 if current_field > lines then current_field = lines end if if curs_posn > length(field_buffers[current_field]) then curs_posn = 1 end if elsif key = insert then imode = not(imode) if imode = 1 then cursor(BLOCK_CURSOR) else cursor(UNDERLINE_CURSOR) end if if imode then printcolor(box[COORDS]+{offset+lines, 1}, {WHITE, BLACK}, "ovr") else printcolor(box[COORDS]+{offset+lines, 1}, {WHITE, BLACK}, "ins") end if elsif key = ENTER then current_field += 1 if current_field > lines then exit end if curs_posn = 1 elsif key = home then current_field = 1 curs_posn = 1 elsif key = bksp then if curs_posn = 1 then field_buffers[current_field] = field_buffers[current_field][2..$] & ' ' else field_buffers[current_field] = field_buffers[current_field][1..curs_posn-2] & field_buffers[current_field][curs_posn..$] & ' ' end if curs_posn -= 1 if curs_posn < 1 then curs_posn = 1 end if elsif key > 31 and key <129 then if WORD_WRAP = 0 then if imode then ovr field_buffers[current_field][curs_posn] = key else ins if curs_posn = 1 then field_buffers[current_field] = key & field_buffers[current_field][1..$-1] else field_buffers[current_field] = field_buffers[current_field][1..curs_posn-1] & key & field_buffers[current_field][curs_posn..$-1] end if end if curs_posn += 1 if curs_posn > length(field_buffers[current_field]) then curs_posn -= 1 end if else word wrap is turned on

some info first str = Fdialogs_rts(field_buffers[current_field]) ready_to_wrap = 0 if length(str) = length(field_buffers[current_field]) then ready_to_wrap = 1 four differing circumstances

1. insert on, curs mid str 2. insert on, curs end str

3. ovr on, curs mid str 4. ovr on, curs end str if curs_posn < length(field_buffers[current_field]) then

printcolor({1,curs_posn}, {WHITE, BLACK}, "!") cursor somewhere in middle if imode then ovr field_buffers[current_field][curs_posn] = key curs_posn += 1 if curs_posn > length(field_buffers[current_field]) then curs_posn -= 1 end if else ins overflow = field_buffers[current_field][$] if curs_posn = 1 then field_buffers[current_field] = key & field_buffers[current_field][1..$-1] else field_buffers[current_field] = field_buffers[current_field][1..curs_posn-1] & key & field_buffers[current_field][curs_posn..$-1] end if if overflow != ' ' then

overflow not ' ' so wrap field_buffers = wrap_fields(field_buffers, current_field, overflow) re-display all fields have_wrapped = 1 end if curs_posn += 1 if curs_posn > length(field_buffers[current_field]) then curs_posn -= 1 end if end if else

cursor position is at the end of the buffer doesn't look like it matters if in ovr or insert mode overflow = key field_buffers = wrap_fields(field_buffers, current_field, overflow)

re-display all fields have_wrapped = 1

next line current_field += 1 if current_field > lines then exit end if

cursor for i = 1 to length(field_buffers[current_field]) do if field_buffers[current_field][i] = ' ' then curs_posn = i exit end if end for

end if

redisplay entire form if have word wrapped if have_wrapped then for i = 1 to lines do printcolor(box[COORDS]+{offset+i-1, 1+start_field}, {WHITE, BLACK}, field_buffers[i]) end for have_wrapped = 0 end if

else length of str is < than length field_buffer

so don't need to check for wrapping if imode then ovr field_buffers[current_field][curs_posn] = key curs_posn += 1 if curs_posn > length(field_buffers[current_field]) then curs_posn -= 1 end if else ins if curs_posn = 1 then field_buffers[current_field] = key & field_buffers[current_field][1..$-1] else field_buffers[current_field] = field_buffers[current_field][1..curs_posn-1] & key & field_buffers[current_field][curs_posn..$-1] end if curs_posn += 1 if curs_posn > length(field_buffers[current_field]) then curs_posn -= 1 end if end if end if end if end if

print current field printcolor(box[COORDS]+{offset+current_field-1, 1+start_field}, {WHITE, BLACK}, field_buffers[current_field]) position(box[COORDS][1] + offset+current_field-1, box[COORDS][2] + curs_posn+start_field)

end if end while

clear the box SetSize(size_x, size_y) position(pcoords[1],pcoords[2]) SetColors(SCREEN_BKGND, SCREEN_BKGND) cur_style = DefaultBox[STYLE] DefaultBox[STYLE] = 5 box = GenericBox({}, {}) DefaultBox[STYLE] = cur_style

return field_buffers end function


global function Form_old(sequence title, sequence fields) fields is a sequence of THREES of sequences,

holding the label, input field, and length of input field most of this is based on the Input function

eg result = Form(sequence title, sequence {sequence label, sequence default, integer field_size (repeat as required) } )


sequence result, box, field_coords, pcoords, input_field integer j, lines, field_count, size_x, size_y, start_field integer max_field_length, current_field, curs_posn, offset atom key, cur_style, field_change, imode key =0 field_change = 0

result = {} pcoords = get_position()

calculate number of lines (1 line = 1 label + 1 field) field_count = length(fields) lines = field_count/3

find max_field_length max_field_length = 0 for i = 3 to field_count by 3 do if fields[i] > max_field_length then max_field_length = fields[i] end if end for

set box size if length(title) > 0 then size_x = lines+3 offset = 3 else size_x = lines+1 offset = 1 end if

size_y = length(fields[1]) + length(fields[2]) + 4 1st 2 fields set width of box - all other fields should be same size size_y = length(fields[1]) + max_field_length + 4 start_field = length(fields[1]) + 2 SetSize(size_x, size_y)

create box box = GenericBox(title, {})

create labels & fields for i = 1 to field_count by 3 do printcolor(box[COORDS]+{offset+i/3, 1}, {box[COLORS][1], box[COLORS][2]},fields[i]) input_field = repeat(' ', fields[i+2]) printcolor(box[COORDS]+{offset+i/3, 1+start_field}, {WHITE, BLACK}, input_field) printat(box[COORDS]+{offset+i/3, 1+start_field}, fields[i+1])

Note - entry fields always white on black end for

position cursor in 1st entry field, and start entry loop current_field = 1 remember, sets of 3! curs_posn = 1 imode = 1 start on overwrite MoveCursor(box[COORDS]+{offset+current_field/3, 1+start_field})

input_field now becomes the buffer input_field = fields[1 + 1] ie first field

while length(input_field) < 3 do input_field = input_field & ' ' end while

while key != ESC do key = get_key() if key > 0 then do nothing if no key pressed - faster key scanning, and cursor flashing

if key = dn or key = ENTER then field_change = 1 write out buffer fields[current_field+1] = input_field current_field = current_field+3 if current_field > field_count then current_field = current_field-3 if key = ENTER then exit end if end if input_field = fields[current_field+1] if length(input_field) < 3 then input_field = input_field & " " end if

elsif key = up then field_change = 1 write out buffer fields[current_field+1] = input_field current_field = current_field-3 if current_field < 0 then current_field = current_field+3 end if input_field = fields[current_field+1] if length(input_field) < 3 then input_field = input_field & " " end if

elsif key = home then current_field = 1 field_change = 1

elsif key = right then curs_posn = curs_posn + 1 if curs_posn > fields[current_field+2] then curs_posn = curs_posn - 1 end if

elsif key = left then curs_posn = curs_posn - 1 if curs_posn = 0 then curs_posn = 1 end if

elsif key = bksp then if curs_posn > 1 then and curs_posn <= length(input_field) then if length(input_field) < curs_posn then while length(input_field) < curs_posn do input_field = input_field & ' ' end while end if curs_posn = curs_posn -1 input_field = input_field[1..curs_posn-1] & input_field[curs_posn+1..length(input_field)] & ' ' end if

elsif key = insert then imode = not(imode) if imode = 1 then cursor(BLOCK_CURSOR) else cursor(UNDERLINE_CURSOR) end if

elsif key > 31 and key <129 then if imode then if curs_posn > length(input_field) then curs_posn = length(input_field)+1 input_field = input_field & key elsif curs_posn > length(input_field) and WORD_WRAP = 1 then move to the next field, taking the last word into the next field else input_field[curs_posn] = key end if curs_posn = curs_posn +1 else input_field = input_field[1..curs_posn-1] & key & input_field[curs_posn .. length(input_field)] curs_posn = curs_posn +1 if length(input_field) > fields[current_field+2] then input_field = input_field[1..fields[current_field+2]] end if

end if if curs_posn > fields[current_field+2] then curs_posn = curs_posn - 1 end if end if

if field_change = 1 then field_change = 0 MoveCursor(box[COORDS]+{offset+current_field/3, 1+start_field}) curs_posn = 1

end if

refresh the current field printcolor(box[COORDS]+{offset+current_field/3, 1+start_field}, {WHITE, BLACK}, input_field)

move the cursor back to its set position MoveCursor(box[COORDS] + {offset+current_field/3, start_field + curs_posn}) end if

end while

write out last field fields[current_field+1] = input_field

clear the box SetSize(size_x, size_y) position(pcoords[1],pcoords[2]) SetColors(SCREEN_BKGND, SCREEN_BKGND) cur_style = DefaultBox[STYLE] DefaultBox[STYLE] = 5 box = GenericBox({}, {}) DefaultBox[STYLE] = cur_style

for i =2 to field_count by 3 do result = append(result, fields[i] ) end for

return result

end function


global constant MF_TEXT = 1, MF_CHECK = 2, MF_LABEL = 3, MF_DROPLIST = 4, MF_BUTTON = 5



global procedure draw_MF(sequence title, sequence form_colors, integer form_row, integer form_col, sequence fields) this takes care of actually drawing the form, notwithstanding input
sequence result, box, blank

result = {} blank = {}

create box SetColors(form_colors[1], form_colors[2]) position(form_row, form_col) box = GenericBox(title, {})

for i = 1 to length(fields) do

labels if fields[i][1] = MF_LABEL then position(form_row + fields[i][2], form_col + fields[i][3])

puts(1, fields[i][4]) printcolor({form_row + fields[i][2], form_col + fields[i][3]}, form_colors, fields[i][4]) end if

text entries if fields[i][1] = MF_TEXT then blank = repeat(' ', fields[i][4]) if length(fields[i][5]) > fields[i][4] then fields[i][5] = fields[i][5][1..fields[i][4]] end if printcolor({form_row + fields[i][2], form_col + fields[i][3]}, {BRIGHT_WHITE, BLACK}, blank) printcolor({form_row + fields[i][2], form_col + fields[i][3]}, {BRIGHT_WHITE, BLACK}, fields[i][5]) end if

check boxes if fields[i][1] = MF_CHECK then position(form_row + fields[i][2], form_col + fields[i][3]) printcolor({form_row + fields[i][2], form_col + fields[i][3]}, form_colors, "[ ] " & fields[i][5]) if fields[i][4] = 1 then position(form_row + fields[i][2], form_col + fields[i][3] + 1) puts(1, "X") end if end if

drop list if fields[i][1] = MF_DROPLIST then blank = repeat(' ', fields[i][4]) printcolor({form_row + fields[i][2], form_col + fields[i][3]}, {BRIGHT_WHITE, BLACK}, "#" & blank & "#") fields[i][6][fields[i][7]] = Fdialogs_rts(fields[i][6][fields[i][7]]) printcolor({form_row + fields[i][2], form_col + fields[i][3] + 1}, {BRIGHT_WHITE, BLACK}, fields[i][6][fields[i][7]]) end if

button if fields[i][1] = MF_BUTTON then

set a blank button button starts and ends with a '+' blank = repeat(' ', fields[i][4])

put the button text into the middle of that, or truncate the text if you have to if length(fields[i][6]) > fields[i][4] - 2 then fields[i][6] = fields[i][6][1..fields[i][4]-2] end if for j = 1 to length(fields[i][6]) do blank[j+1] = fields[i][6][j] end for blank[1] = '[' blank[$] = ']' display the button printcolor( {form_row + fields[i][2], form_col + fields[i][3] }, {form_colors[1], form_colors[2] }, blank ) end if

end for

end procedure


global function mf_text(sequence field, sequence form_colors, integer form_row, integer form_col)


sequence return_val, buffer, blank integer max_length, curs_posn atom c

return_val = {{}, 0} field[5] = Fdialogs_rts(field[5]) max_length = field[4] blank = repeat(' ', max_length) buffer = blank curs_posn = length(field[5]) + 1

if curs_posn > max_length then curs_posn = max_length end if if curs_posn = 0 then curs_posn = 1 end if

transfer field text to buffer if length(field[5]) > 0 then for i = 1 to max_length do if i > length(buffer) or i > length(field[5]) then exit end if buffer[i] = field[5][i]

set cursor position position(form_row + field[2], form_col + field[3] + curs_posn - 1) end for else set cursor position position(form_row + field[2], form_col + field[3] + curs_posn - 1) end if

while 1 do c = get_key() if c > 0 then if c = ENTER then return_val[2] = ENTER return_val[1] = buffer exit elsif c = ESC then return_val[2] = ESC return_val[1] = buffer exit elsif c = dn then return_val[2] = dn return_val[1] = buffer exit elsif c = up then return_val[2] = up return_val[1] = buffer exit elsif c = bksp then if curs_posn <= length(buffer) then buffer[curs_posn] = ' ' end if curs_posn -= 1 if curs_posn < 1 then curs_posn = 1 end if buffer[curs_posn] = ' ' printcolor({form_row + field[2], form_col + field[3]}, {BRIGHT_WHITE, BLACK}, buffer) position(form_row + field[2], form_col + field[3] + curs_posn -1 ) elsif c = right then curs_posn += 1 if curs_posn > length(buffer) then curs_posn -= 1 end if position(form_row + field[2], form_col + field[3] + curs_posn -1 ) elsif c = left then curs_posn -= 1 if curs_posn < 1 then curs_posn = 1 end if position(form_row + field[2], form_col + field[3] + curs_posn -1 ) elsif (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or (c

= '0' and c <= '9') or (c >= 32 and c <= 126) and curs_posn <= max_length then buffer[curs_posn] = c curs_posn += 1 printcolor({form_row + field[2], form_col + field[3]}, {BRIGHT_WHITE, BLACK}, buffer) position(form_row + field[2], form_col + field[3] + curs_posn -1 ) end if end if end while

field[5] = Fdialogs_rts(buffer) return_val[1] = field

return return_val end function


global function mf_check(sequence field, sequence form_colors, integer form_row, integer form_col)


sequence return_val atom c

return_val = {{}, 0}

set cursor position position(form_row + field[2], form_col + field[3] + 1)

while 1 do c = get_key() if c > 0 then if c = dn or c = right then return_val[2] = dn exit elsif c = up or c = left then return_val[2] = up exit elsif c = ' ' or c = ENTER then field[4] = (field[4] - 1) * -1 if field[4] = 1 then printcolor({form_row + field[2], form_col + field[3] + 1}, form_colors, "X") else printcolor({form_row + field[2], form_col + field[3] + 1}, form_colors, " ") end if position(form_row + field[2], form_col + field[3] + 1) elsif c = ESC then return_val[2] = c exit end if end if end while

return_val[1] = field

return return_val end function


global function mf_droplist(sequence field, sequence form_colors, integer form_row, integer form_col)


sequence return_val, blank atom c integer orig

blank = {} return_val = {{}, 0} set cursor position position(form_row + field[2], form_col + field[3])

change color to reverse blank = repeat(' ', field[4]) printcolor({form_row + field[2], form_col + field[3]}, {BLACK, WHITE}, "#" & blank & "#") field[6][field[7]] = Fdialogs_rts(field[6][field[7]]) printcolor({form_row + field[2], form_col + field[3] + 1}, {BLACK, WHITE}, field[6][field[7]])

while 1 do c = get_key() if c > 0 then if c = ESC then return_val[2] = ESC exit elsif c = up then return_val[2] = up exit elsif c = dn then return_val[2] = dn exit elsif c = ' ' or c = ENTER then position(form_row + field[2], form_col + field[3]) SetSize(field[5], field[4]) SetColors(BLACK, WHITE) orig = field[7] field[7] = ListBoxIndex("", field[6], field[7]) if field[7] = -1 then field[7] = orig end if exit end if end if end while

return_val[1] = field

return return_val end function


function mf_button(sequence field, sequence form_colors, integer form_row, integer form_col)


sequence return_val, blank atom c integer orig

blank = {} return_val = {{}, 0} set cursor position position(form_row + field[2], form_col + field[3])

reverse colour blank = repeat(' ', field[4]) put the button text into the middle of that, or truncate the text if you have to if length(field[6]) > field[4] - 2 then field[6] = field[6][1..field[4]-2] end if for j = 1 to length(field[6]) do blank[j+1] = field[6][j] end for blank[1] = '[' blank[$] = ']'

display the button printcolor( {form_row + field[2], form_col + field[3] }, {form_colors[2], form_colors[1] }, blank )

the input cycle

this control responds to esc, cursor, and enter while 1 do c = get_key()

if c = ESC then return_val[2] = ESC exit elsif c = up or c = left then return_val[2] = up exit elsif c = dn or c = right then return_val[2] = dn exit elsif c = ENTER then return_val[2] = ENTER oh, what the hell, flash the button again! printcolor( {form_row + field[2], form_col + field[3] }, {WHITE, RED}, blank ) Delay(0.1) printcolor( {form_row + field[2], form_col + field[3] }, {form_colors[2], form_colors[1] }, blank ) exit elsif c > -1

new topic     » goto parent     » topic index » view message » categorize

6. Re: Structured Programming: QB IS STRUCTURED!!!

{Laughs} I started oin an IBM PCjr 8088.  People were showing off their
386's when I got the machine.  I think the best machine I had for years was=

a 486, and I finally got a really old pentium someone tossed.  Not a lot of=

money for software.  If I'm supposed to ladel out a ton of money for
software, I'd want it to be something I really enjoy.  Trainz comes to mind=

right away.  Open TTD, but, that's freeware.

I've been coding in QB for years.  I've always wanted to learn something=

new, but every time I tried, I was told that to learn, say, C, I had to
learn super sophiisticated FOIL and stuff.  I was also told that I needed t=
o
understand super abstract stuff, and since my coding is focused more on app=
s
and simple games {I wanna' write a remake of OMF2097, which is the best
fighting game ever, because rather than give you hundreds of thousands of=

fighters to choose from, they allowed you to configure your own}, I never=

really needed anything else.  Then I went to send a friend a game I wrote,=

and they couldn't run it.  Mebbe it's time for a change? {Giggles}

Love & Friendship & Blessed Be!
Lynn Erika Kilroy


>From: Vincent <guest at RapidEuphoria.com>
>Reply-To: EUforum at topica.com
>To: EUforum at topica.com
>Subject: Re: Structured Programming: QB IS STRUCTURED!!!
>Date: Tue, 17 Jan 2006 09:14:00 -0800
>
>
>posted by: Vincent <darkvincentdude at yahoo.com>
>
>Chris Burch wrote:
>
> > Why? I haven't used QBASIC for 20 years.
>
>There you go. smile
>
>I'm comfused at why Lynn would be using such old programming technology in=

>2006! I mean considering that there is a newer generation of Visual Basic=

>and .NET tools offered by Microsoft. Qbasic has not been supported for a=

>good decade I think, and is virtually dead today. In fact, the operating=

>system it was designed to run on is also dead. We have a buggy emulation o=
f
>it now (if that) which is only suitable for toying around, running ancient=

>software, or developing batch file scripts.
>
>If Lynn went into a chatroom with discussion about modern programming,
>they'd quickly laugh when they discover how enthusatstic Lynn is about
>ancient Qbasic!
>
>No affense Lynn.
>
>
>Regards,
>Vincent
>
>
>
>

new topic     » goto parent     » topic index » view message » categorize

7. Re: Structured Programming: QB IS STRUCTURED!!!

Vincent wrote:
> 
> Chris Burch wrote:
> 
> > Why? I haven't used QBASIC for 20 years.
> 
> There you go. smile
> 
> I'm comfused at why Lynn would be using such old programming technology in
> 2006!
> I mean considering that there is a newer generation of Visual Basic and .NET
> tools offered by Microsoft. Qbasic has not been supported for a good decade
> I think, and is virtually dead today. In fact, the operating system it was
> designed
> to run on is also dead. We have a buggy emulation of it now (if that) which
> is only suitable for toying around, running ancient software, or developing
> batch file scripts.
> 
> If Lynn went into a chatroom with discussion about modern programming, they'd
> quickly laugh when they discover how enthusatstic Lynn is about ancient
> Qbasic!
> 
> No affense Lynn.

Actually, QBasic is still very popular with numerous websites, forums, and
chatrooms devoted to it. It even experienced a jump in recent years since the
open-source clone FreeBASIC came out. You can still find books on QBasic at any
bookstore and new ones get released (and rereleased) occasionally. I almost
recently bought the QBasic version of "Numerical Recipes" off Amazon since my
dept. at work lost our Fortran version (I ended up not buying it after finding a
co-worker who had the C edition). I also used QB professionally until about 2004
or something when I started using Euphoria for our simple/throwaway DOS stuff.
Also, interesting fact, Ken Silverman (the creator of the BUILD engine used in
Duke Nukem 3D, Shadow Warrior, Blood, Redneck Rampage, etc.) still writes the
code for his projects in QBasic for testing before porting it to C for
efficiency.


The Euphoria Standard Library project :
    http://esl.sourceforge.net/
The Euphoria Standard Library mailing list :
    https://lists.sourceforge.net/lists/listinfo/esl-discussion

new topic     » goto parent     » topic index » view message » categorize

8. Re: Structured Programming: QB IS STRUCTURED!!!

D. Newhall wrote:

<snip>

> I almost recently bought
> the QBasic version of "Numerical Recipes" off Amazon since my dept. at work
> lost our Fortran version (I ended up not buying it after finding a co-worker
> who had the C edition).

<snip>

Just in case you didn't know ... blink
The book "Numerical Recipes in C" is also _freely_ available online here:
   http://www.library.cornell.edu/nr/cbookcpdf.html

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu