home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
forth
/
compiler
/
fpc
/
source
/
wfl.seq
< prev
next >
Wrap
Text File
|
1991-02-11
|
17KB
|
436 lines
\ WFL.SEQ Window file selection. by Tom Zimmer
ONLY FORTH ALSO HIDDEN DEFINITIONS ALSO
create rootdir '.' c, 0 c, \ root is . & null
handle dirhndl
defer wflbutton ' noop is wflbutton
headerless
create itemstk 10 allot
itemstk 10 erase
variable item#
item# off
variable flitem
flitem off
: setfl ( n1 --- )
flitem ! ;
\ Item stack used to hold Directory offsets in window while stepping
\ up and down the directory tree.
: 0istk ( --- ) \ Clear the item stack
itemstk 10 erase
item# off ;
: >istk ( n1 --- ) \ put an item on the item stack
item# @ itemstk + c!
item# @ 1+ 9 min item# ! ;
: istk> ( --- n1 ) \ get an item from the item stack.
item# @ 1- 0MAX dup item# !
itemstk + dup c@ swap off ;
headers
create dirspec$ ," *.*" b/hcb allot
-1 dirspec$ >hndle !
dirspec$ count + off
create defdirspec$ ," *.*" 20 allot
14 constant b/fnam \ bytes per filename
300 constant maxdir
4 constant forgx
3 constant forgy \ top of file window display
18 constant dlen \ directory window length
b/fnam maxdir *D 64. d+ \ room for directory entries plus a couple
pointer dirseg
0 value dirrow
0 value #fls \ number of files present
0 value curfl \ current file number
0 value foff
headerless
16 constant dirattrib \ directory file attribute
variable aletter
\ headers
\
\ : dirinit ( --- ) \ try to initialize the directory
\ defers initstuff \ yet initialized.
\ dirseg 0=
\ if ." \n\bNo room for directory buffer!, "
\ ." Can't pop up Dir window. Sorry!\n\:10"
\ then rows forgy - 4 - =: dlen ;
\
\ ' dirinit is initstuff
\
\ headerless
: dirseg_release ( -- )
unpointer> dirseg ;
code foff+ ( n1 --- n2 )
pop ax
add ax, ' foff >body
1push
end-code
headers
code >fadr ( name# -- seg name_offset )
pop ax
mov bx, # b/fnam
mul bx \ b/fnam *
add ax, # 1 \ 1+
mov dx, ' dirseg >body \ dirseg
2push
end-code
: dir>pad ( seg off --- a1 n1 )
2dup c@l >r ?cs: pad r@ 1+ cmovel pad 1+ r> ;
: .nam ( n1 --- )
>fadr dup>r dir>pad dup>r type
12 r> - spaces
dirseg r> 1- c@l dirattrib and
if #out @ 1- #line @ at
." ∞"
then ;
: name>buf ( --- ) \ move name from dta to buffer
#fls >fadr nip >r
pad 30 + 12 dup 0
do over i + c@ 0=
if drop i leave
then
loop dup dirseg r@ c!l
>r ?cs: swap dirseg r> r@ 1+ swap cmovel
pad 21 + c@ dirseg r> 1- c!l ;
: $getdir ( a1 --- )
dirhndl $>handle \ get directory spec
dirhndl pathset drop
off> curfl
off> foff
off> #fls
dirseg 0= ?exit \ leave if no directory space
pad SET-DTA
dirhndl >nam findfirst
begin 255 and 0= #fls maxdir > 0= and
while name>buf incr> #fls
findnext
repeat ;
\ 05/25/90 tjz added from Mike Christopher
: sortdir ( -- ) \ rearrange directory to ascending ascii order
#fls 2 > if
#fls 1- 0 ?do
#fls i 1+ ?do
i >fadr 1- ?cs: pad 120 + b/fnam cmovel
j >fadr 1- ?cs: pad 150 + b/fnam cmovel
pad 121 + count pad 151 + count rot max comp 0<
if
?cs: pad 120 + j >fadr 1- b/fnam cmovel
?cs: pad 150 + i >fadr 1- b/fnam cmovel
then
loop
loop
then
;
: getdir ( --- )
dirspec$ $getdir sortdir ; \ 05/25/90 tjz
headerless
: (at.") ( x1 y1 | text --- x1 y1+1 )
2dup at
2r@ 2dup c@l >r 1+ r@ typeL r> 1+ xeven r> + >r
1+ ;
: at." ( x1 y1 | text --- x1 y1+1 )
compile (at.") x," ; immediate
: showkeys ( --- ) \ show some help
forgx forgy 17 -1 d+
at." ┌────────────────┐"
at." │ Hom │ │ PgUp │"
at." │ ────┼───┼───── │"
at." │ End │ │ PgDn │"
at." ├────────────────┴─────────────────────┐"
at." │ A-Z = Next file starting with Letter │"
at." │ ─┘ = Select file or directory │"
at." │ Esc = Cancel file selection │"
at." │ Del = Delete selected file │"
at." │ \ = Type in a new Directory Spec. │"
at." └──────────────────────────────────────┘" 2drop ;
: pathbox ( --- )
forgx forgy 17 10 d+ 2dup 52 2 d+ box&fill
." Path = " ;
: showpath ( --- )
pathbox forgx forgy 26 11 d+ at
dirspec$ dup pathset 0=
if count type
else ." Can't read path" drop
then ;
headers
: showdir ( --- ) \ display directory window
savecursor
forgx forgy 1- 2dup 15 dlen 1+ d+ box
forgx 15 + forgy at ." \r"
forgx 15 + forgy dlen + at ." \r"
dlen 0
do forgx forgy 1 i d+ at i foff+ #fls >=
if i 0= if ." ...No Files..."
else ." " then
else curfl i foff+ =
if i =: dirrow
>attrib1 ." ■" i foff+ .nam ." ■"
>norm
else ." " i foff+ .nam ." "
then
then
loop restcursor ;
: nfl ( --- ) \ next file
curfl #fls 1- 0MAX = if exit then
curfl 1+ #fls 1- min 0MAX dup !> curfl
dup #fls < swap dlen 1- - foff = and
if foff 1+ #fls 15 - 0MAX min !> foff
then ;
: pfl ( --- ) \ previous file
curfl 1- 0MAX dup !> curfl
foff =
if foff 1- 0MAX !> foff
then ;
headerless
: ?lmatch ( --- f1 )
curfl >fadr 1+ c@l aletter c@ = ;
: gotofl ( --- )
flitem @ 0MAX
curfl over >
if curfl swap do pfl loop
else curfl ?do nfl loop
then ;
: 0fl ( --- ) \ first file
0 !> curfl
0 !> foff ;
variable foffsave
variable curflsave
: find_letter ( c1 --- c1 ) \ search for a file starting with c1
95 and dup aletter c! curfl >r
curfl #fls 1- 0MAX =
if 0fl
else nfl
then
begin ?lmatch curfl #fls 1- 0MAX = or 0=
while nfl
repeat ?lmatch 0=
if 0fl r@ 0
?do ?lmatch ?leave nfl
loop ?lmatch
\ 05/25/90 tjz fix per Mike Christopher
if curflsave @ curfl - 1+ dlen >=
if
foff foffsave ! curfl curflsave !
then
then
else foff foffsave ! curfl curflsave !
then ?lmatch 0= if beep then
r>drop ;
: efl ( --- ) \ goto end of file list
begin nfl curfl #fls 1- 0MAX = until ;
headers
\ a1 = counted string address
: >pathend ( a1 --- a2 ) \ a2 = the address of the char beyond last \
>pathend" drop ;
: >pathend-1 ( a1 --- a2 )
dup c@ >r \ save old length
dup>r >pathend \ find last backslash
r@ - 2- 0MAX r@ c! \ adjust to new count
r@ >pathend \ find previous backslash
r> r> swap c! ; \ restore old length
headerless
: delfl ( --- ) \ delete the current file
curfl >fadr dup>r 1- c@l dirattrib and
forgx forgy 19 11 d+ 2dup at 50 spaces at
if ." Can't delete directory !\b\:10"
else ." Delete \`" dirseg r@ dir>pad type ." \` <- Y/N [N] "
cursor-on key cursor-off bl or 'y' =
if dirspec$ >pathend dirspec$ 1+ - dup dirhndl c!
dirspec$ 1+ dirhndl 1+ rot cmove
dirseg r@ dir>pad >r dirhndl count + r@ cmove
r> dirhndl c+!
dirhndl count + off
dirhndl hdelete 5 =
if ." Access denied !\b\:10"
then
then curfl foff
getdir
!> foff !> curfl
then r>drop showpath ;
: ndir ( --- ) \ Enter a NEW directory spec
forgx forgy 17 14 d+ at
." Edit the Directory Spec, and press Enter. ESC=Cancel"
cursor-on pathbox
on> autoclear
>attrib1
forgx forgy 26 11 d+ dirspec$ 41 lineeditor drop
>norm
forgx forgy 17 14 d+ at 52 spaces
dirspec$ count + 1- c@ dup '\' = swap ':' = or
if defdirspec$ count >r dirspec$ count + r@ cmove
r> dirspec$ c+!
then dirspec$ c@ 0=
if defdirspec$ dirspec$ over c@ 1+ cmove
then 0 dirspec$ count + c!
dirspec$ pathset drop
cursor-off getdir showpath 0fl ;
: keytests ( n1 --- )
dup false = if ( do nothing ) else
( up arrow ) dup 200 = over 56 = or if pfl else
( down arrow ) dup 208 = over 50 = or if nfl else
( PgUp ) dup 201 = over 57 = or if dlen 2/ 0 ?do pfl loop else
( PgDn ) dup 209 = over 51 = or if dlen 2/ 0 ?do nfl loop else
( \ ) dup 92 = if ndir else
( 0 to 9) dup '0' '9' between over bl or
( A to Z) 'a' 'z' between or if find_letter else
( Del ) dup 211 = over 46 = or if delfl else
( Home ) dup 199 = over 55 = or if 0fl else
( End ) dup 207 = over 49 = or if efl else beep
then then then then then then then then then then
drop ;
: ?setdir ( c1 --- c2 f1 ) \ return bool false if new dir
curfl >fadr dup>r 1- c@l dirattrib and \ are we on a DIR
#fls 0> and \ and have anything
if drop
dirseg r@ dir>pad + off \ move DIR to PAD, nul term
pad 1+ @ rootdir @ = \ is DIR the ROOT?
if dirspec$ 2+ c@ ':' = \ include drive?
if '\' dirspec$ 3 + c! 3 dirspec$ c!
defdirspec$ count >r
dirspec$ count + r@ cmove r> dirspec$ c+!
else defdirspec$ dirspec$ over c@ 1+ cmove
then dirspec$ count + off \ nul term
begin item# @ 1 > \ Clear DIR stack
while istk> drop
repeat istk> setfl \ set to ROOT
else pad 1+ @ " .." drop @ = \ pop one level?
if \ Now we need to remove a Dir from DIRSPEC$.
\ so step through DIRSPEC to next to the last
\ directory.
dirspec$ >pathend-1 dirspec$ 1+ - dirspec$ c!
\ Append *.* to current directory specification
defdirspec$ count >r dirspec$ count + r@ cmove
r> dirspec$ c+!
dirspec$ count + off \ nul terminate
istk> setfl \ pop DIR stack
else \ Must be on a directory name other than
\ "." or ".." so step down to that directory
dirspec$ >pathend dup \ set dirspec length
dirspec$ 1+ - dirspec$ c!
\ append DIR from PAD
\ to dirspec
pad count >r swap r@ cmove
r> dirspec$ c+! \ set length
" \" >r dirspec$ count + r@ cmove \ append "\"
r> dirspec$ c+!
defdirspec$ count >r dirspec$ count + r@ cmove
r> dirspec$ c+! \ append *.*
dirspec$ count + off \ null terinate
curfl >istk \ save directory offset
0 setfl \ reset offset to zero
then
then \ get new directory, and show the path
cursor-off getdir showpath gotofl
false false
else true
then r>drop ;
headers
FORTH DEFINITIONS
: <getfile> ( --- <a1> f1 ) \ return a1 filename addr and boolean
rows forgy - 4 - =: dlen
dirseg 0= if false exit then \ if it didn't work, then leave
['] wflbutton save!> dobutton \ init mouse support
savecursor
savescr \ save cursor and screen
forgx 2- forgy 2- over 74 + rows 3 - box&fill
forgx forgy 36 1 d+ at \ then my message
." \r Tom's Window File Selection Tool "
forgx forgy 20 7 d+ at
." \2 Reading Directory Files... "
cursor-off getdir \ clear screen, and get dir
0fl showkeys showpath \ show the keys and dir path
forgx forgy 17 16 d+ at \ and som help information
." Use to pick a file, or press the first letter of"
forgx forgy 17 17 d+ at
." the file you want, then press Return to select it."
begin showdir 0 0 at \ show the directory
key dup 13 = dup \ wait for a key, if Enter
if drop ?setdir ( c1 --- c2 f1 ) \ try to set dir
then over 27 = or 0= \ else check for escape or null
while keytests \ if neither then try to find a file
repeat 13 = dup \ if it was Enter, then get the file name
\ we are on and move it to PAD. Prepend
\ the DIR spec.
if dirspec$ >pathend dirspec$ 1+ - >r
dirspec$ pad r@ 1+ cmove r> pad c!
curfl >fadr 2dup c@l >r 1+
?cs: pad count + r@ cmovel r> pad c+!
pad handle>ext c@ '.' <> \ append '.' if no extension
if '.' pad count + c!
1 pad c+!
then pad swap
then
restscr \ restore screen
restcursor \ restore cursor position
restore> dobutton
#fls 0=
if dup
if 2drop false \ discard addr even if found if
\ no files in list
then
then dirseg_release ; \ return boolean for file selected
' <getfile> is getfile \ patch in window get file.
behead