Metropoli BBS
VIEWER: editwin.asm MODE: TEXT (ASCII)
	.MODEL	SMALL

	INCLUDE	equates.inc
	INCLUDE	instance.inc
	INCLUDE	messages.inc
	INCLUDE	objects.inc

	MaxSize		EQU	BufSize-10	;Maximum number of characters
	WindowWidth	EQU	29		;Column width of edit window
	ScrollCols	EQU	WindowWidth-4	;Number of columns to scroll

IF1
	INCLUDE	macros.mac
	INCLUDE	objects.mac
ENDIF

	EXTRN	disCharacter:NEAR
	EXTRN	makeActive:NEAR
	EXTRN	sendMsg:NEAR

	EXTRN	Buffer:WORD
	EXTRN	Cursor:WORD
	EXTRN	Dispatch:WORD
	EXTRN	Keyboard:WORD
	EXTRN	Self:WORD
	EXTRN	SBorder:WORD
	EXTRN	Window:WORD

	.CODE

IF Dbug
	PUBLIC	initEditWinVars
ENDIF
COMMENT	%
==============================================================================
Sets EditWin's instance variables with values handed down from the master.

=============================================================================%
initEditWinVars	PROC	NEAR
	push		Self
	getInst$	ch,Row1,MasterObj	;Get upper row from master
	getInst		cl,Col1			;Get left column
	getInst		dh,Row2			;Get lower row
	getInst		dl,Col2			;Get right column

	add		ch,RowOffset		;Add in row offset
	add		ch,RowOffset		;Add in row offset
	mov		dh,ch
	add		dh,2
	add		cl,ColOffset		;Add in column offset
	add		cl,ColOffset		;Add in column offset
	mov		dl,cl
	add		dl,WindowWidth+4

	setInst		Row1,ch,EditWin		;Set upper row
	setInst		Col1,cl			;Set left column
	setInst		Row2,dh			;Set lower row
	setInst		Col2,dl			;Set right column
	setInst		InxPtr,0,,2		;Clear char count

	inc		ch
	setInst		Row1,ch,Cursor		;Set cursor row
	add		cl,ColOffset		;Add in column offset
	setInst		Col1,cl			;Set cursor column
	pop		Self
	ret
initEditWinVars	ENDP



COMMENT	%
==============================================================================
Displays an ASCII character, or performs a function based on the last key
event.

=============================================================================%
handleEvent	PROC	NEAR
	getInst		ah,ScanCode,Keyboard	;Get scan code
	null		ah,hdl1			;Invalid key - Exit

	getInst		al,AsciiCode		;Get char code
	moreThan	al,126,hdl1		;> 126? - Exit
	lessThan	al,32,hdl2		;< 32? - Check if command
	call		disChar			;Display if char
	jmp		hdl1

hdl2:	call		processCmd		;Process if command
hdl1:	ret
handleEvent	ENDP



COMMENT	%
==============================================================================
Processes keyboard commands based on ASCII and scan codes for EditWin.

Passed:	al - Character code

=============================================================================%
processCmd	PROC	NEAR
	lea		si,EditWinDispTbl	;Get addr of dispatch tbl
pcmd1:	eq		al,Bptr[si],pcmd2	;Match ASCII code? - Exit loop
	add		si,3			;Else - Point to next entry
	identity	Bptr[si],pcmd1		;More? - Keep looking
pcmd2:	call		Wptr[si+1]		;Call procedure
	ret
processCmd	ENDP



COMMENT	%
==============================================================================
Displays an ASCII character in the EditWindow.

Passed:	al - Character code

=============================================================================%
disChar	PROC	NEAR
	call		getInstVars		;Get instance variables
	neq		cx,MaxSize,dchr1	;Room in buffer? - Skip
	call		invalidKey		;Else - Alert user
	jmp		dchr3			;Exit

dchr1:	add		di,cx			;Point to end of buffer
	mov		Bptr[di],bh		;Save new char there
	mov		Bptr[di+1],0		;Save zero in next position
	inc		cx			;Increment char count
	setInst		InxPtr,cx		;Save new count

	getInst		dl,Col1,Cursor		;Get cursor column
	neq		dl,al,dchr2		;Not at edge? - Skip
	push		si			;Else - Save obj ptr
	send		Self,ScrollLeft,ScrollCols
	pop		si			;Restore obj ptr

dchr2:	call		disCharacter		;Display character
	inc		dl			;Increment column
	setInst		Col1,dl			;Update cursor column
dchr3:	ret
disChar	ENDP



COMMENT	%
==============================================================================
Returns important EditWindow instance variables.

Passed:	al - Character code

Passes:	ax - Lower/Right row/column
	bh - Character code
	bl - Color
	cx - Character count
	di - Text input buffer pointer
	dx - Upper/Left row/column

=============================================================================%
getInstVars	PROC	NEAR
	getInst		dh,Row1,Self		;Get upper row
	inc		dh			;Increment row
	getInst		dl,Col1			;Get left column
	add		dl,ColOffset		;Add in column offset

	getInst		bl,Color		;Get color
	mov		bh,al			;Pass char code in bh

	getInst		ah,Row2			;Get lower row
	dec		ah
	getInst		al,Col2			;Get right column
	sub		al,ColOffset		;Subtract column offset

	getInst		cx,InxPtr		;Get character count
	getInst		di,TxtPtr		;Get text input buffer addr
	ret
getInstVars	ENDP



IF Dbug
	PUBLIC	backSpace
ENDIF
COMMENT	%
==============================================================================
Deletes the character to left of cursor scring if necessary.

=============================================================================%
backSpace	PROC	NEAR
	call		getInstVars		;Get instance variables
	notZero		cx,bksp1		;Chars in buffer? - Skip
	call		invalidKey		;Else - Alert user
	jmp		bksp3			;Exit

bksp1:	dec		cx			;Decrement char count
	setInst		InxPtr,cx		;Save new count
	add		di,cx			;Point to last char in buffer
	mov		Bptr[di],0		;Replace with a zero

	mov		al,dl			;Get left column
	getInst		dl,Col1,Cursor		;Get cursor column
	dec		dl			;Decrement column
	setInst		Col1,dl			;Update cursor column
	neq		dl,al,bksp2		;Not at edge? - Skip
	send		Self,ScrollRight,ScrollCols

bksp2:	mov		bh,Space		;Pass blank character
	call		disCharacter		;Display character
bksp3:	ret
backSpace	ENDP



COMMENT	%
==============================================================================
Scrolls a line of text to the left.

Passed:	StackTop - Number of columns to scroll

=============================================================================%
scrLeft	PROC	NEAR
	call		getInstVars		;Get instance variables
	add		di,cx			;Point to end of text
	sub		di,WindowWidth		;Point to 1st char in window
	getStackArgs	cx			;Get #columns to scroll
	add		di,cx			;Point to new 1st char
	mov		ax,WindowWidth		;Calculate loop count
	sub		ax,cx
	mov		cx,ax

scrl1:	mov		bh,Bptr[di]		;Get character
	call		disCharacter		;Display it
	inc		dl			;Next column
	inc		di			;Next character
	loop		scrl1

	dec		dl
	setInst		Col1,dl,Cursor		;Update cursor position
	ret
scrLeft	ENDP



IF Dbug
	PUBLIC	scrRight
ENDIF
COMMENT	%
==============================================================================
Scrolls a line of text to the right.

Passed:	StackTop - Number of columns to scroll

=============================================================================%
scrRight	PROC	NEAR
	call		getInstVars		;Get instance variables
	zero		cx,scrr2		;No chars in buffer? - Exit

	add		di,cx			;Point to end of text
	getStackArgs	ax			;Get #columns to scroll
	lessThan	cx,ax,scrr3		;Not enough chars? - Skip
	mov		cx,ax			;Set up loop counter
scrr3:	sub		di,cx			;Point to 1st char in window

scrr1:	mov		bh,Bptr[di]		;Get character
	call		disCharacter		;Display it
	inc		dl			;Next column
	inc		di			;Next character
	loop		scrr1

	setInst		Col1,dl,Cursor		;Update cursor position
scrr2:	ret
scrRight	ENDP



COMMENT	%
==============================================================================
Alerts user as to invalid input.

=============================================================================%
invalidKey	PROC	NEAR
	push		Self
	send		Dispatch,Update		;Alert user
	pop		Self
	ret
invalidKey	ENDP



	.DATA

EditWinDispTbl	LABEL	WORD
	DB	008
	DW	OFFSET backSpace
	DB	Nil
	DW	OFFSET invalidKey

defMsg	EditWin,\
	Refresh,\
	<initEditWinVars,,>

defMsg	EditWin,\
	Read,\
	<handleEvent,,makeActive>

defMsg	EditWin,\
	ScrollLeft,\
	<,,scrLeft>

defMsg	EditWin,\
	ScrollRight,\
	<,,scrRight>

defObj	EditWin,\
	<Window,SBorder>,\
	<Row1,1,11,\
	Col1,1,17,\
	Row2,1,13,\
	Col2,1,36,\
	Color,1,34h,\
	Unused,1,Nil,\
	TxtPtr,2,Buffer,\
	InxPtr,2,0,\
	MasterObj,2,Nil>,\
	<Refresh,Read,ScrollLeft,ScrollRight>



	END

[ RETURN TO DIRECTORY ]