home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
RiscOS
/
APP
/
DEVS
/
FORTH
/
WIMPFO.ZIP
/
!WimpForth
/
windows
< prev
next >
Wrap
Text File
|
1996-03-21
|
19KB
|
715 lines
\ window classes
cr .( Loading generic wimp windows support...)
comment:
You will usually use WINDOWs by sending them a Start: message
passing the initial position. And you will close the window
by sending a Stop: message, what else.
GENERIC-WINDOWs are linked in a list so that the APPLICATION can
distribute the Wimp messages to the right GENERIC-WINDOW. (see pause')
WINDOWs are special GENERIC-WINDOWs which can respond to the
Wimp messages (On_*****: messages in WINDOW). You can do other
things with WINDOWs before opening them: SetTitleText: , Move: ,
GetSize: , Center: (get initial position so it will be centered
on the screen) and Print: .
Start: will Create: the WINDOW, then Open: it.
Create: sends a On_Init: message, then Move: and Build: itself.
Build: will create the memory structure for Wimp_CreateWindow.
When you say Stop: to a WINDOW, it Close: s and Delete: s itself.
The latter will invoke the newest On_Done: method.
So you may control the appearing and disappearing of WINDOWs in
several stages.
The basic work being done we can define a TEXT-WINDOW which
can display text. PutText: , PutCR: , BackSpace: , Cls: will
tell it what to display. You can control the cursor position.
The class EDIT-WINDOW can additionally gain the caret, although
I must admit that the handling is very incomplete.
CKey is a class to realise a circular key buffer. This could
be a place where keypresses to an application could be stored.
APPLICATIONs will distribute messages which arrive with them.
Keypresses to an object of CKey (PutKey:) , mouse clicks to the
appropriate WINDOW or ICONBAR-ICON (On_Click:)
In the end this file redefines the in/output deferred words
of the Forth system to work with windows.
comment;
code Wimp_CreateWindow ( buf -- hndl )
mov r1, tos
swi " Wimp_CreateWindow"
mov tos, r0
next c;
code Wimp_DeleteWindow ( buf -- )
mov r1, tos
swi " Wimp_DeleteWindow"
ldmfd sp !, { tos }
next c;
code Wimp_OpenWindow ( buf -- )
mov r1, tos
swi " Wimp_OpenWindow"
ldmfd sp !, { tos }
next c;
code Wimp_CloseWindow ( buf -- )
mov r1, tos
swi " Wimp_CloseWindow"
ldmfd sp !, { tos }
next c;
code Wimp_RedrawWindow ( blk -- f )
mov r1, tos
swi " Wimp_RedrawWindow"
mov tos, r0
next c;
code Wimp_UpdateWindow ( blk -- f )
mov r1, tos
swi " Wimp_UpdateWindow"
mov tos, r0
next c;
code Wimp_GetRectangle ( buf -- f )
mov r1, tos
swi " Wimp_RedrawWindow"
mov tos, r0
next c;
code OS_Plot ( y x type -- )
mov r0, tos
ldmfd sp !, { r1, r2, tos }
swi " OS_Plot"
next c;
code Wimp_Initialise ( ^messages ^descr "TASK" osver -- thndl osver' )
mov r0, tos
ldmfd sp !, { r1, r2, r3 }
swi " Wimp_Initialise"
stmfd sp !, { r1 }
mov tos, r0
next c;
code Wimp_CloseDown ( "TASK" taskhndl -- )
mov r0, tos
ldmfd sp !, { r1, tos }
swi " Wimp_CloseDown"
next c;
code Wimp_Poll ( [^pollword] buf mask -- buf event )
mov r0, tos
tst r0, # &400000
ldmfd ne sp !, { r1, r3 }
ldmfd eq sp !, { r1 }
swi " Wimp_Poll"
mov tos, r0
stmfd sp !, { r1 }
next c;
code Wimp_SetCaretPosition ( index hght y x ihndl whndl -- )
mov r0, tos
ldmfd sp !, { r1, r2, r3, r4, r5, tos }
swi " Wimp_SetCaretPosition"
next c;
code Wimp_BlockCopy ( dymin dxmin symax sxmax symin sxmin whndl -- )
mov r0, tos
ldmfd sp !, { r1, r2, r3, r4, r5, r6, tos }
swi " Wimp_BlockCopy"
next c;
code Wimp_ReportError ( ^title flags ^errorblock -- res )
mov r0, tos
ldmfd sp !, { r1, r2 }
swi " Wimp_ReportError"
mov tos, r1
next c;
code Wimp_ForceRedraw ( ymax xmax ymin xmin whnd -- )
mov r0, tos
ldmfd sp !, { r1, r2, r3, r4, tos }
swi " Wimp_ForceRedraw"
next c;
code Wimp_GetWindowState ( block -- )
mov r1, tos
swi " Wimp_GetWindowState"
ldmfd sp !, { tos }
next c;
code Wimp_SendMessage ( Hicon Htask block eventcode -- )
mov r0, tos
ldmfd sp !, { r1, r2, r3, tos }
swi " Wimp_SendMessage"
next c;
code -32* ( n -- n' )
mov tos, tos, lsl # 5
rsb tos, tos, # 0
next c;
\ &1 constant WF_TitleBar
&2 constant WF_Movable
\ &4 constant WF_VScrollBar
\ &8 constant WF_HScrollBar
&10 constant WF_WimpRedraws
&20 constant WF_Pane
&40 constant WF_Outside
\ &80 constant WF_NoBack/Close
&100 constant WF_ScrollReqAR
&200 constant WF_ScrollReq
&400 constant WF_GCOLours
&800 constant WF_NoBelow
&1000 constant WF_HotKeys
&2000 constant WF_StayOnScreen
&4000 constant WF_IgnoreR
&8000 constant WF_IgnoreL
&10000 constant WF_Open?
&20000 constant WF_OnTop?
&40000 constant WF_FullSize?
&80000 constant WF_ToggleSize?
&100000 constant WF_InputFocus?
&200000 constant WF_ForceOnScreen?
&81000000 constant WF_BackIcon
&82000000 constant WF_CloseIcon
&84000000 constant WF_TitleBar
&88000000 constant WF_ToggleSizeIcon
&90000000 constant WF_VScrollBar
&a0000000 constant WF_AdjSizeIcon
&c0000000 constant WF_HScrollBar
0 value windows-link
0 value applobj
0 value applwin
0 value barpopup
0 value lastpopup
0 value outwindow
create block 44 allot
:class generic-window <super object <classpointer
int hWnd
:m ClassInit: ( -- )
0 to hWnd
here windows-link , to windows-link
self , ;m
:m GetHandle: ( -- n )
hWnd ;m
:m ZeroWindow: ( -- )
0 to hwnd ;m
:m ~: ( -- )
windows-link cell+ @ self =
if windows-link @ to windows-link
else windows-link
begin dup @ ?dup
while dup cell+ @ self =
if @ swap ! exitm then
nip
repeat
then ;m
;class
:class window <super generic-window <classpointer
int xmin
int ymin
int xmax
int ymax
int xscroll
int yscroll
int behindhndl
int wflags
int ti/wacolour
int sb/ticolour
int waxmin
int waymin
int waxmax
int waymax
int TiIFlags
int WBType
int sprarea
int minsize
12 bytes title
int #icons
int mypopup
64 bytes title"
int ?open
: SetSize { dx dy -- }
screen-size
cells 44 - dy ymin + min to ymax
2* 22 - dx xmin + min to xmax ;
:m GetSize: ( -- x y )
xmax xmin - ymax ymin - ;m
: SetMinSize ( x y -- )
16 lshift swap &ffff and or to minsize ;
:m SetTitleText: ( ^str -- )
dup c@ 12 <
if count >r title r@ move 0 title r> + c!
TiIFlags [ IF_IndData invert ] literal and to TiIFlags
else count tuck title" place
title 8 + ! title" 1+ title ! title cell+ on
TiIFlags IF_IndData or to TiIFlags
then ;m
: SetTiColour ( fg bg sel -- )
&ff and 16 lshift sb/ticolour &ffff and or to sb/ticolour
&ff and 8 lshift swap &ff and or
ti/wacolour &ffff0000 and or to ti/wacolour ;
: SetWaColour ( fg bg -- )
&ff and 8 lshift swap &ff and or 16 lshift
ti/wacolour &ffff and or to ti/wacolour ;
: SetWaSize ( x y -- )
0 to waxmin 0 to waymax
negate to waymin to waxmax ;
: SetSBColour ( in out -- )
&ff and swap &ff and 8 lshift or
sb/ticolour &ff0000 and or to sb/ticolour ;
: SetScrollPos ( x y -- )
to yscroll to xscroll ;
: ChangeWFlags ( n mask -- )
wflags and or to wflags ;
:m ClassInit: ( -- )
ClassInit: super
640 320 SetSize
640 320 SetWaSize
0 0 SetMinSize
[ IF_Text nostack1
IF_Border or
IF_HCentered or
IF_VCentered or
IF_FilledBG or ] literal to TiIFlags
c" Window" SetTitleText: self
[ WF_Movable
WF_WimpRedraws or
WF_Outside or
WF_ScrollReqAR or
WF_IgnoreR or
WF_IgnoreL or
WF_BackIcon or
WF_CloseIcon or
WF_VScrollBar or
WF_AdjSizeIcon or
WF_HScrollBar or
WF_ToggleSizeIcon or
WF_TitleBar or ] literal 0 ChangeWFlags
1 to sprarea
Gray1 Gray3 SetSBColour
Black Gray2 Cream SetTiColour
Black White SetWaColour
BT_1/Drag/2 to WBType
-1 to behindhndl 0 to #icons
0 to mypopup ;m nostack1
:m Move: { px py -- }
screen-size
cells 44 - py ymax ymin - + min to ymax py to ymin
2* 22 - px xmax xmin - + min to xmax px to xmin ;m
:m Center: ( -- x y )
screen-size cells ymax ymin - - 2/
swap 2* xmax xmin - - 2/ swap ;m
:m Build: ( ad -- ad' )
^base cell+ ( hWnd ) over
88 move 88 + ;m
:m On_Init: ( -- )
;m
:m On_Done: ( -- )
;m
:m Delete: ( -- )
On_Done: [[ self ]]
hWnd block !
block Wimp_DeleteWindow
0 to hWnd ;m
:m Create: ( x y -- )
hWnd if Delete: self then
On_Init: [[ self ]]
Move: self
here 512 + aligned dup Build: [[ self ]] drop
Wimp_CreateWindow to hWnd ;m
:m Open: ( -- )
hWnd 0= if xmin ymin Create: self then
^base Wimp_OpenWindow
true to ?open ;m
:m Close: ( -- )
hWnd block !
block Wimp_CloseWindow
false to ?open ;m
:m Start: ( x y -- )
hwnd 0= if Create: self else Move: self then
Open: self ;m
:m Stop:
Close: self
Delete: self ;m
:m On_Open: ( block -- )
cell+
lcount to xmin lcount to ymin
lcount to xmax lcount to ymax
lcount to xscroll lcount to yscroll
@ to behindhndl
Open: self ;m
:m On_Close: ( block -- )
drop Close: self ;m
:m On_Menu: ( block -- )
mypopup
if dup @ 64 - swap 4 + @ start: mypopup
mypopup to lastpopup
else drop then ;m
:m On_Select: ( block -- )
drop ;m
:m On_Adjust: ( block -- )
drop ;m
:m On_Click: ( block -- )
dup 8 + c@
case 4 of On_Select: [[ self ]] endof
2 of On_Menu: [[ self ]] endof
1 of On_Adjust: [[ self ]] endof
nip
endcase ;m
:m &popup: ( -- ^obj )
&> mypopup ;m
:m Print:
." Window@" ^base . ." Title: "
TiIFlags IF_IndData and
if title" count type
else title zcount type
then ;m
;class
: ErrorBox ( z"ErrorText -- res )
z" Message from WimpForth"
%10010011
rot Wimp_ReportError ;
:class text-window <super window
int cols
int rows
int xcur
int ycur
int &thescreen
int &endscreen
int &title
:m ClassInit: ( ^title cols rows -- )
ClassInit: super
0 WF_WimpRedraws invert ChangeWFlags
to rows to cols
cols 16* rows 5 lshift 2dup
SetSize SetWaSize
SetTitleText: self ;m
:m On_Init: ( -- )
rows cols * dup allocate abort" Not enough Heap!"
tuck to &thescreen 2dup blank
+ to &endscreen ;m
:m On_Done: ( -- )
&thescreen free drop
0 to &thescreen 0 to &endscreen ;m
2variable plotpos
code rectcalc ( cols block -- ad len #lines y x )
ldr r2, [ tos, # 16 ]
ldr r0, [ tos, # 24 ]
sub r2, r2, r0 \ r2=work_y0
ldr r0, [ tos, # 40 ]
sub r2, r2, r0
mov r3, r2, lsr # 5
ldmfd sp !, { r1 }
mul r3, r1, r3
and r2, r2, # &1f
add r0, r0, r2
sub r0, r0, # 2
ldr r1, [ tos, # 32 ]
sub r1, r0, r1
add r1, r1, # &1f
mov r1, r1, lsr # 5
ldr r2, [ tos, # 4 ]
ldr r4, [ tos, # 20 ]
sub r2, r2, r4 \ r2=work_x0
ldr r4, [ tos, # 28 ]
sub r5, r4, r2
ldr r2, [ tos, # 36 ]
add r3, r3, r5, lsr # 4
and r5, r5, # &f
sub tos, r4, r5
sub r2, r2, tos
add r2, r2, # &f
mov r2, r2, lsr # 4
stmfd sp !, { r0, r1, r2, r3 }
next c;
: DoRectangle
cols 2r@ drop
rectcalc ( ad len #lines y x )
plotpos 2! 0
?do plotpos 2@ 188 OS_Plot \ position on the screen
over &thescreen + dup &endscreen >= if drop leave then
over \ determine string to print
-trailing OS_WriteN \ print it
-32 plotpos cell+ +! \ bump screen pos
swap cols + swap \ bump source
loop 2drop ;
:m On_Redraw: ( block -- )
dup>r Wimp_RedrawWindow
begin while
DoRectangle
r@ Wimp_GetRectangle
repeat r>drop ;m
: Update ( x1 y1 x2 y2 -- ) \ 1=bottom left
-32* block dup>r 16 + ! \ 2=top right
16* r@ 12 + ! 1+ -32* r@ 8 + ! 16* r@ 4 + !
hWnd r@ !
r@ Wimp_UpdateWindow
begin while
DoRectangle
r@ Wimp_GetRectangle
repeat r>drop ;
: Update+Clear ( x1 y1 x2 y2 -- )
-32* swap 16* 2swap 1+ -32* swap 16*
Hwnd Wimp_ForceRedraw ;
: PutText ( ad len -- x y )
dup xcur + cols - dup 0>=
if - else drop then tuck
&thescreen ycur cols * + xcur + swap cmove
xcur ycur rot +to xcur ;
: UpdateText ( x y -- )
xcur ycur Update ;
:m PutText: ( ad len -- )
PutText UpdateText ;m
: Scroll ( -- )
&thescreen cols + &thescreen rows 1- cols * dup>r cmove
&thescreen r> + cols blank
rows 1- -32* 0 -32 cols 16* rows -32* 0 hWnd Wimp_BlockCopy ;
:m PutCR: ( -- )
0 to xcur
ycur 1+ rows =
if Scroll
0 rows 1- cols over Update+Clear
else 1 +to ycur then ;m
:m BackSpace: ( -- )
xcur if -1 +to xcur
xcur ycur xcur 1+ over Update+Clear
else 7 OS_WriteC then ;m
:m Cls: ( -- )
&thescreen cols rows * blank
0 rows 1- cols 0 Update+Clear
0 to xcur 0 to ycur ;m
:m GetXY: ( -- x y )
xcur ycur ;m
:m GotoXY: ( x y -- )
to ycur to xcur ;m
:m GetColRow: ( -- col row )
cols rows ;m
;class
:class CKey <super object
132 bytes &keybuf
:m ClassInit:
0 &keybuf w! ;m
:m IsKey?: ( -- f )
&keybuf count swap c@ <> ;m
: bump &keybuf + dup c@ 2 + &7f and swap c! ;
:m PutKey: ( c -- )
&keybuf count swap c@ 2 - &7f and <>
if &keybuf count + 1+ w! 0 bump
else drop beep then ;m
:m GetKey: ( -- c )
&keybuf count over c@ <>
if count + w@ 1 bump
else drop -1 then ;m
:m On_Key: ( block -- )
24 + w@ PutKey: self ;m
;class
:class edit-window <super text-window <classpointer
:m ClassInit: ( cols rows -- )
ClassInit: super
BT_Click to WBType ;m
: SetCaret ( -- )
0 &02000020
ycur 1+ -32* xcur 16*
-1 Hwnd
?open if Wimp_SetCaretPosition
else 2drop 2drop 2drop then ;
:m On_Select: ( block -- )
drop SetCaret ;m
:m PutText: ( ad len -- )
PutText ( SetCaret ) UpdateText ;m
:m PutCR: ( -- )
0 to xcur
ycur 1+ rows =
if Scroll else 1 +to ycur then
( SetCaret )
0 ycur cols over Update+Clear ;m
:m GetTheCaret: ( -- )
SetCaret ;m
;class
also classes
: getwin ( block -- block obj )
dup @ windows-link
begin ?dup
while 2dup cell+ @ GetHandle: [[ ]] =
if nip cell+ @ exit then
@
repeat abort" Window not found!" ;
: zero-windows ( -- )
windows-link
begin ?dup
while dup cell+ @ ZeroWindow: [[ ]] @
repeat ;
previous
0 value OSVer
0 value TaskHndl
variable pausecfa
: .platform
." RISC OS " base @ >r decimal
OSVer 0 <# # # ascii . hold # #> type space r> base ! ;
s" WimpForth Window" drop 1- 80 25 edit-window mainwindow
mainwindow dup to outwindow to applwin
:class iconbar-icon <super icon <classpointer
:m ClassInit: ( ^str -- )
[ IF_Sprite IF_IndData or BT_Click or ] literal 0
ChangeIFlags: iconblock
SetText: iconblock
WH_IconBarR to hWnd
0 0 Move: iconblock
68 68 SetSize: iconblock
0 to hIcon ;m
:m On_Click: ( blk -- )
dup 8 + c@
case 2 of @ 64 - -96 start: barpopup
barpopup to lastpopup endof
4 of drop open: mainwindow
GetTheCaret: mainwindow endof
endcase ;m
;class
" !wimpforth" drop 1- iconbar-icon ibicon
defer On_DataLoad ( ad len -- )
also classes
:class application <super object <classpointer
CKey keybuf
create PollBuf 256 allot
: pause'
PollBuf 0 Wimp_Poll
case
1 of On_Redraw: [[ getwin ]] endof
2 of On_Open: [[ getwin ]] endof
8 of On_Key: applobj endof
\ 12 of On_GainCaret: [[ getwin ]] endof
\ 11 of On_LoseCaret: [[ getwin ]] endof
9 of On_MenuSelection: applobj endof
6 of On_Click: applobj endof
3 of On_Close: [[ getwin ]] endof
17 of On_UMessage: applobj endof
18 of On_UMessageRec: applobj endof
\ 19 of On_UMessageAck: [[ getwin ]] endof
\ 7 of On_DragBox: [[ getwin ]] endof
\ 4 of On_PointerLeaving: [[ getwin ]] endof
\ 5 of On_PointerEntering: [[ getwin ]] endof
\ 10 of On_ScrolReq: [[ getwin ]] endof
\ 13 of On_NonZeroPollWord: [[ getwin ]] endof
( otherwise ) nip ( the pointer to block )
endcase ;
:m ClassInit:
applobj abort" Only one Application!"
self to applobj ;m
create d&dbuf 64 allot
: message ( block -- )
case dup 16 + @
0 of drop bye endof
3 of dup 44 + zcount d&dbuf place
dup 8 + @ over 12 + !
4 over 16 + !
0 swap dup 4 + @ swap 17 Wimp_SendMessage pause
d&dbuf count On_DataLoad endof
nip
endcase ;
:m On_UMessageRec: ( block -- ) message ;m
:m On_UMessage: ( block -- ) message ;m
:m Start: ( -- )
block off
block z" WimpForth" &4b534154 310 Wimp_Initialise
to OSVer to TaskHndl
['] pause' ['] pause dup @ pausecfa ! call!
['] pause' is outpause
zero-windows
Create: ibicon ;m
:m On_Click: ( block -- )
dup 12 + @ -2 =
if ibicon
else dup 12 + getwin nip then
On_Click: [[ ]] ;m
:m On_MenuSelection: ( block -- )
Execute: lastpopup ;m
:m On_Key: On_Key: keybuf ;m
:m IsKey?: ( -- f ) IsKey?: keybuf ;m
:m PutKey: ( c -- ) PutKey: keybuf ;m
:m GetKey: ( -- c ) GetKey: keybuf ;m
;class previous
: wpushkey ( c -- )
PutKey: applobj ;
: w"pushkeys ( a1 n1 -- ) \ push the characters of string a1,n1
0max 127 min bounds
?do i c@ pushkey
loop ;
: loadit s" fload " "pushkeys "to-pathend" "pushkeys 13 pushkey ;
' loadit is On_DataLoad
' wpushkey is pushkey
' w"pushkeys is "pushkeys
: wtype ( ad len -- )
PutText: outwindow outpause ;
: wemit ( c -- )
dup bl <
if
case
7 of 7 OS_WriteC endof
8 of BackSpace: outwindow endof
10 of PutCR: outwindow endof
endcase
else sp@ 1 wtype drop then ;
: wcr PutCR: outwindow ;
: wcrtab PutCR: outwindow
tabing? 0= ?exit
first-line?
if left-margin indent + spaces false to first-line?
else left-margin spaces tab-margin spaces
then ;
: wkey? pause IsKey?: applobj ;
: wkey begin pause IsKey?: applobj until
GetKey: applobj ;
: wgetcolrow GetColRow: outwindow ;
: wgetxy GetXY: outwindow ;
: wgotoxy GotoXY: outwindow ;
: wcol wgetcolrow drop 1- min wgetxy drop - spaces ;
: w?cr wgetxy drop + wgetcolrow drop > if cr then ;
: wcls Cls: outwindow ;
: window-io ( -- ) \ reset to Forth IO words
['] wemit is emit
['] wtype is type
['] wcrtab is cr
['] w?cr is ?cr
['] wkey is key
['] wkey? is key?
['] wcls is cls
\ ['] cls is page
['] wgotoxy is gotoxy
['] wgetxy is getxy
['] wgetcolrow is getcolrow
['] wcol is col ;
forth-io-chain chain-add window-io
: exit-stuff ( -- )
bye-chain do-chain 0 &58454241 0 os_exit ;
' exit-stuff is bye
: .leaving
." Leaving..." cr ;
: ExitWimp &4b534154 TaskHndl Wimp_CloseDown ;
bye-chain chain-add .leaving
bye-chain chain-add ExitWimp