TweetFollow Us on Twitter

Text with Style
Volume Number:4
Issue Number:5
Column Tag:Forth Forum

Formatted Text with Style

By Jörg Langowski, MacTutor Editorial Board

TextEdit with Style(s)

TextEdit has always been one of the major conveniences of the Macintosh. Life (as far as programming is concerned) is so much simpler with a standard editing package that takes care of line break, word wrap, text insertion, justification etc. for you, instead of having to write it yourself.

One major reason why TextEdit was inadequate for e.g. word processing had always been that the text style was fixed for one text edit record, i.e. for one piece of edited text. Changing fonts, boldfacing, or changing the size of only one word or one phrase in the text was not possible.

The new implementation of TextEdit that is described in IM Vol.V finally introduces this possibility. TextEdit now recognizes two types of TE records: the old one, having the same text style all over the text, and a new format where style information is associated and displayed with the text. Although contained in IM V, the new TextEdit traps are available (System 4.2 and later) on the Mac Plus as well as on the SE and MacII.

A second inconvenience has been resolved: When working on new type TE records, TECopy and TEPaste now uses the desk scrap (i.e. the general clipboard) for cutting/pasting directly. It is no more necessary to convert between the internal TE scrap and the desk scrap on activate/deactivate events. For old TE records, TECopy and TEPaste still only use the internal scrap (for compatibility).

The new text edit is not yet used very widely, but it is worth it. Therefore I thought it might be a good idea to show its function on a practical example in Mach2 Forth. It is based on the ‘skeleton editor’ on the Mach2 demo disk, but contains a lot of enhancements, such as horizontal scrolling and scroll thumbs that work, and of course the text style support.

The new TE record

How does the system distinguish between the new and the old type TE record?

Mostly, the structure of the new record is the same as the old one, with a couple of exceptions: The txSize field of a new TE record contains -1 (word, offset $50 from beginning of record). In that case, the fields txFont and txFace (offset $4A and $4C) are combined to hold the handle of what is called a style record, a structure that contains the style information associated with the text. Of course, the information previously contained in the txFont, txFace and txSize fields - font, text face, and font size - is not meaningful anymore, since it may change over the length of the text.

Furthermore, the fields lineHeight and fontAscent (offset $18 and $1A) may now also contain -1, in which case the line height and ascent will be calculated individually for each line; if they contain positive numbers, the TErecord has fixed line height and ascent as before.

The style record

This structure contains the style information that belongs to the TErecord. Its layout is give in IM V-261 and I’ll repeat it here (Pascal style):

TYPE
TEStyleHandle = ^TEStylePtr;
TEStylePtr = ^TEStyleRec;
TEStyleRec = RECORD
 nRuns: INTEGER;
 nStyles: INTEGER;
 styleTab:STHandle;
 lhTab: LHHandle;
 teRefCon:LONGINT;
 nullStyle: nullSTHandle;
 runs:  ARRAY [0..0] OF StyleRun
 END;

StyleRun = RECORD
 startChar: INTEGER;
 styleIndex:INTEGER
 END;

The text is characterized by a succession of style runs, characters of the same style in the TE record. The system knows where they start (startChar) and the index styleIndex of the corresponding style in a style table. Each style record contains information about how many style runs and how many different styles there are in the text (nruns, nStyles), and handles to the style and line height tables (styleTab, lhTab). teRefCon can be used freely by the application, and nullStyle contains a handle to the style table that is used when the selection is empty.

The style table contains an entry for each different style encountered in the text:

TYPE
STHandle = ^STPtr;
StPtr = ^TEStyleTable;
TEStyleTable = ARRAY [0..0] OF STElement;

STElement = RECORD
 stCount: INTEGER;
 stHeight:INTEGER;
 stAscent:INTEGER;
 stFont:INTEGER;
 stFace:Style;
 stSize:INTEGER;
 stColor: RGBColor;
 END;

stCount indicates how often this style occurs in the text; the remaining fields indicate the text style.

Since the line height now may differ from line to line, there is another table, the line-height table, which contains an entry for each line in the lineStarts array of the TE record.

TYPE
LHHandle = ^LHPtr;
LHPtr = ^LHTable;
LHTable = ARRAY [0..0] OF LHElement;

LHElement = RECORD
 lhHeight:INTEGER;
 lhAscent:INTEGER;
 END;

For each line, lhHeight and lhAscent contain the maximum height and ascent present in that line.

Fortunately, you don’t have to remember any of this information when using the new Text Edit. For straightforward text editing, all we need to know is that the TECopy, TECut, TEKey and TEDelete routines work as before, but Copy and Cut store a second type of scrap, ‘styl’, in the desk scrap. When you do a TEPaste, this information is not used and only the text is pasted into the edit record using the style that was present at the insertion point. For pasting ‘with style’, a new routine exists, TEStylPaste. This is one of 10 routines that are called through the new trap TEDispatch. This trap will look at a selector (integer) on top of stack and call the new text edit routines accordingly.

Mach2 implements the new TE routines using their names and compiling the glue code for the dispatch routine automatically. One routine, TEStylInsert, has been left out accidentally, and is redefined in the example listing. Two more new traps exist: TEStylNew and TEGetOffset. Mach2 spells the former ‘TEStyleNew’, so watch out for that.

For simple use as in the example, the most important new routines that you have to remember are TEStylNew, TEStylPaste, TEGetOffset, TEGetStyle, and TESetStyle.

TEStylNew is just like TENew, except that it creates a new type TE record. TEStylPaste will use the ‘styl’ information in the scrap, if present, for the text to be pasted.

TEGetOffset works with both old and new type TE records and finds the character offset in the text corresponding to a certain point in the window (local coordinates). This is necessary for updating the font, size and style menu information after a change of the insertion point by a mouse click.

TEGetStyle and TESetStyleare used to get and set style information at the selection of insertion point in the text. They work with another data structure, the TextStyle:

TYPE TextStyle = RECORD
 tsFont:INTEGER;
 tsFace:Style;
 tsSize:INTEGER;
 tsColor: RGBColor
 END;

This record contains the text style information that is passed to/from the TE record.

All these routines are, of course, documented in IM Vol. V. Examples on how to call them can be found in the program listing. Feel free to experiment with the other new TE routines.

The example will create an editor window with vertical and horizontal scroll bars and read the first 1024 characters from a text file. You can use this text for playing around with different style settings (using the menus I provided). Doing this, you will notice that the Style menu doesn’t seem to have any effect on the text. Fonts and font sizes may be changed, but underlining, boldfacing etc. seems to be impossible. However, when you set those text attributes for a certain selection and then click at different positions in the text, you will see that the Style menu changes appropriately, checkmarks appear and disappear in the right positions. Therefore I believe that the style changes are well recorded in the style record/style table; only the text display doesn’t seem to function. Is this a bug still present in the new TextEdit, or have I overlooked something obvious (question to you, the readers)?

You see that editing multi-style text is not too difficult with the new TE routines, since they take care of almost everything. For saving and loading files, you would have to provide code that reads/writes the style record information together with the text, this also seems pretty straightforward. Printing a new style text edit record is a completely different ballgame, since no printing support exists (yet?) that is quite as extensive as the new TextEdit. You would have to extract the style information for each line, using the style record, style and line height tables, and write the printing code from scratch. More difficult, but probably a good ‘exercise for the reader’.

Bugs in the SCSI driver?

Some remarks have been received that the SCSI code published in V4#1/2 was buggy, and someone seems to have crashed his hard disk using it. I feel sorry if application of that example (which was however marked ‘experimental’) should have caused trouble to anyone. The only excuse I have is that it was said that the code had been shown to work only for two types of disk, the Q280 and the ST225N, the only ones available to me for testing at that time.

Let me point out here that we can only do our best to give examples of Macintosh programming, but never guarantee that everything works 100% and bug-free. Feel free to publish your comments, preferably with corrections, in MacTutor, that’s what we’re here for. But for any example that is printed here or published on the source code disks, be prepared that something might go wrong, and especially DON’T run it from the disk that has your only copy of that 40-page report on it that is due in two days! Play it safe and use floppies that have nothing valuable on them. I learned my lesson when I crashed my own hard disk while writing the Forth example for the February article.

I wish you good luck with this month’s example. The source code disk contains two compiled versions, one for Mac Plus/SE/II, and one for Mac II only (contains 68020 code). As far as I have checked them, they don’t crash and work under MultiFinder. But you never know...

Till next month, happy threading.

Listing 1: Text Edit Example with Style
\ New Text Edit example
\ J. Langowski for Mac Tutor March 1988
\ derived from
\ Editor Shell Example Program on Mach 2 demo disk

\ found two ‘features’ of the new text edit while 
\ experimenting:
\ a. when the insertion point is at a boundary between
\    two different styles, the text typed will be TEKeyed 
\    according to the style BEFORE the insertion point,
\    while TEGetStyle will return style information from 
\    AFTER the insertion point.
\ b. Although the text face seems to be set inside the style \    record 
and properly associated with the text 
\    (TEGetStyle returns the correct information after the 
\    text face has been changed), the text is always drawn 
\    plain text style. The font and size changes work OK.
\

only forth definitions
also assembler also mac

\ ***** constants

300 CONSTANT APPLEID 
310 CONSTANT FILEID
320 CONSTANT EDITID
330 CONSTANT SIZEID
340 CONSTANT FontID
350 CONSTANT StyleID

20  CONSTANT InUpArrow   
21  CONSTANT InDownArrow 
22  CONSTANT InPageUp 
23  CONSTANT InPageDown
129 CONSTANT InThumb

$44525652 Constant “drvr
$464F4E54 Constant “font

%000001000000000 CONSTANT ShiftMask 
    
$10 CONSTANTportRect \ Grafport rectangle
$6E CONSTANTwVisible \ visible flag [byte]

\ text edit equates
0  CONSTANT teDestRect  
8  CONSTANT teViewRect  
$C  CONSTANTselRect
$18 CONSTANT   teLineHite 
$1A CONSTANTteFontAscent
$1C CONSTANTteSelPoint  
$20 CONSTANT   teSelStart 
$22 CONSTANT   teSelEnd
$38 CONSTANT   teCarOn  
$39 CONSTANT   teCarAct
$3C CONSTANTteLength
$3E CONSTANTteTextH
$48 CONSTANTteCROnly
$4A CONSTANTteFont
$4C CONSTANTteFace
$4A CONSTANTteStylHandle  
 \ handle to style record for new
 \ text edit. Never accessed directly
$4E CONSTANTteMode \ text mode [word] 
$50 CONSTANT   teSize\ font size [word] 
 \ teFont, teFace, teMode, teSize are only 
 \ meaningful for old style TE records.
 \ for a new style record, teSize contains -1.
 \ in that case, teFont and teFace together contain
 \ the handle to the style record.
$5E CONSTANTteNLines
$60 CONSTANTteLines

$AB0 CONSTANT  TEScrpLength
$AB4 CONSTANT  TEScrpHandle

\ Event Record Equates
$0 CONSTANT What ( event code [word] )
$2 CONSTANT Message( event message [long] )  
$6 CONSTANT When ( ticks since start-up  [long] )
$A CONSTANT Where( mouse loc. pt. global [long] )
$E CONSTANT Modifiers( modifier flags  [word] )

$0A CONSTANT LF  ( ascii ‘linefeed’ )
$20 CONSTANT SP  ( ascii ‘space’ )

create applestring 01 C, $14 C, \ Apple symbol

\ ***** variables

VARIABLE TEHandle( handle for text edit record )
VARIABLE TERect   4 VALLOT
 ( Text Edit view rectangle )
VARIABLE SIZE    ( item# of current textsize )
VARIABLE DESKNAME 252 VALLOT\ holds name of desk accessory
VARIABLE FONTNAME 252 VALLOT\ holds font name selected
VARIABLE ITEMNAME 60 VALLOT 
 \ receives menu item name
VARIABLE MyStyle 8 VALLOT 
 \ text style record for our private use
 \ fields of MyStyle:
 0 CONSTANT tsFont
 2 CONSTANT tsFace
 4 CONSTANT tsSize
 6 CONSTANT RGBColor
VARIABLE currentFont \ menu ID of font in use
VARIABLE #fonts      \ # of currently installed fonts
VARIABLE currentSize  \ menu ID of size in use

76  USER AbortHook
152 USER ContentHook
160 USER GrowHook
164 USER CloseBoxHook
168 USER UpdateHook
172 USER ActivateHook
202 USER CAction \ control action routine vector

\ ***** glue routines for new text edit
\
\ TEStylNew ( destRect viewRect -- TEHandle )
\ is misspelled ‘TEStyleNew’ in the Mach2 trap definitions,
\ but implemented. So are TEGetOffset and most of the 
\ other new text edit routines that are called through 
\ TEDispatch.
\ One exception is TEStylInsert, which we are defining 
\ here:

CODE TEStylInsert ( text length hST hTE -- )
 EXG D4,A7
 MOVE.L $C(A6),-(A7) \ pointer to text
 MOVE.L $8(A6),-(A7) \ length of text
 MOVE.L $4(A6),-(A7) \ style record handle
 MOVE.L (A6),-(A7) \ TE record handle
 ADDA.W #$10,A6
 MOVE.W #$7,-(A7)
 _TEDispatch
 EXG  D4,A7
 RTS
END-CODE

\ ***** windows, menus, controls, tasks etc. *****

NEW.WINDOW Editor
“ Editor” Editor TITLE
42 4 330 507 Editor BOUNDS
DOCUMENT INVISIBLE CLOSEBOX GROWBOX 
 Editor ITEMS

200 1000 TERMINAL EditTask

NEW.MBAR EditBar 

NEW.MENU AppleMenu
APPLESTRING AppleMenu TITLE
0 APPLEID AppleMenu BOUNDS
“ About Editor ...;(-” AppleMenu ITEMS

NEW.MENU FileMenu
“ File” FileMenu TITLE
0 FileID FileMenu BOUNDS
“ New/N;Open.../O;Close;Save;Save as...;Revert to Original;(Print”
 FileMenu ITEMS

NEW.MENU EditMenu
“ Edit” EditMenu TITLE
0 EDITID EditMenu BOUNDS
“ (Undo/Z;(-;Cut/K;Copy/C;Paste/V;Clear” 
 EditMenu ITEMS

NEW.MENU FontMenu
“ Font” FontMenu TITLE
0 FontID FontMenu BOUNDS
“  (Fonts<I;(-” FontMenu ITEMS

NEW.MENU SizeMenu
“ Size” SizeMenu TITLE
0 SizeID SizeMenu BOUNDS
“  9 Point; 10 Point; 12 Point; 14 Point; 18 Point; 20 Point; 24 Point” 

 SizeMenu ITEMS

CREATE SizeIDTable
0 , 0 , 0 c, \ no menu IDs for sizes 0 thru 8
1 c, 2 c, 0 c, 3 c, \  9,10,--,12
0 c, 4 c, 0 c, 0 c, \ --,14,--,--
0 c, 5 c, 0 c, 6 c, \ --,18,--,20
0 c, 0 c, 0 c, 7 c, \ --,--,--,24

CREATE SizeTable
0 c, 9 c, 10 c, 12 c, 14 c, 18 c, 20 c, 24 c,


NEW.MENU StyleMenu
“ Style” StyleMenu TITLE
0 StyleID StyleMenu BOUNDS
“  Plain/P; Bold/B<B; Italic/I<I; Underline/U<U; Outline<O; Shadow<S; 
Condense; Extend” 
 StyleMenu ITEMS

NEW.CONTROL Scroll
VSCROLLBAR VISIBLE 100 0 Scroll ITEMS
VARIABLE lastVs
400 CONSTANT maxVs

NEW.CONTROL hScroll
HSCROLLBAR VISIBLE 100 0 hScroll ITEMS
VARIABLE lastHs
100 CONSTANT maxHs

: CHECK  ( menuhandle item# flag -- )( checking a menu item )
 CALL CheckItem ;
 
: =string { aStr bStr | -- flag }
 aStr count 65536 * bStr count rot + swap
 call CmpString 0=
;

CODE @TEHandle
 MOVE.L TEHandle,-(A6)    RTS
END-CODE

: Shift?   (   -  f )   \ checks the event record to see if the
 \ shift key was pressed. 
 EVENT-RECORD Modifiers + W@ ShiftMask AND
 IF -1 ELSE 0 THEN  
;
 

: adjustFontMenu
\ adjust font menu and currentFont variable
 myStyle w@ ( font ID ) fontName call getFname
 #fonts @ 0 DO
 fontMenu @ i itemName call GetItem
 itemName fontName =string 
 IF  FontMenu @ currentFont @ 0 check 
 \ uncheck previous font selection 
     FontMenu @ i -1 check
     i currentFont !
     leave
 THEN
 LOOP
;

: adjustStyleMenu { | face - }
 myStyle tsFace + w@ -> face
 8 0 DO 
   1 i scale face and ( get style bit )
   if -1 else 0 then
   styleMenu @ i 2+ rot check 
 LOOP 
;
 
: adjustSizeMenu
 SizeMenu @ currentSize @ 0 check 
 myStyle tsSize + w@ ( size )
 SizeIDTable + c@ ( sizeID )
 dup currentSize !
 SizeMenu @ swap -1 check 
;

: getCurrentStyle { | LHite FAsc -- }
 ( updates variable currentFont )
 ( size and Face kept in myStyle )
 ( LHite and FAsc are currently not used )

 @TEHandle @ teselStart + w@ 
 \ get start of selection (or insertion point)
 ( offset ) myStyle ^ LHite ^ FAsc @TEHandle
 call TEGetStyle
 
 adjustFontMenu
 adjustStyleMenu
 adjustSizeMenu
;

: AdjustTERect
 \ adjust terect size for the presence of scrollbars
 portRect Editor + 4 + W@ ( get bottom coord )
 16 -   ( subtract 16 for height of scrollbar )
 teViewRect @TEHandle @ + 4 + W! \ store new coord back in text edit 
record 
   
 portRect Editor + 6 + W@ ( get right coord )
 16 -   ( subtract 16 for width of scrollbar )
 teViewRect @TEHandle @ + 6 + W!
;
 
: Visible? (   -  f  ) \ checks visible flag in window record
 Editor wVisible + C@  
;

\ ***** event handlers *****

: ACTIVATE-HANDLER
 RUN-ACTIVATE
 EVENT-RECORD Modifiers + W@( get modifiers word )
 1 AND IF 
 @TEHandle CALL TEActivate
 getCurrentStyle
 ELSE   
 @TEHandle CALL TEDeactivate
 THEN 
;

 
: UPDATE-HANDLER
 Editor CALL SetPort
 AdjustTERect
 Editor CALL BeginUpdate
    Editor CALL DrawControls
    Editor CALL DrawGrowIcon
    Editor portRect + @TEHandle CALL TEUpdate
 Editor CALL EndUpdate
;

: CONTENT-HANDLER { | theMouse -- }
 RUN-CONTENT
 Editor CALL SetPort

 ^ theMouse CALL GetMouse
 theMouse @TEHandle @ TEViewRect + 
 call PtInRect
 IF
 theMouse Shift? @TEHandle CALL TEClick
 getCurrentStyle 
 THEN
;

: CLOSEBOX-HANDLER
 Editor \ windowpointer 
 EVENT-RECORD Where + @ call TrackGoAway     IF Editor CALL HideWindow 
THEN
;


\ **** main editor example code *****

: POP-UP
 Editor CALL ShowWindow
 Editor CALL SelectWindow
 EditBar @ CALL SetMenuBar
 CALL DrawMenuBar 
;
 
: ShutDown
 Editor CALL HideWindow
 PAUSE  ( PAUSE so that the i/o task can 
 have a turn and handle the
 deactivate event generated by
  the closing of the window )
 MACH.MBAR( MACH menubar back on screen )
 @TEHandle CALL TEDispose   
;

: SetScrollLimits
 Scroll @ 0 CALL SetMinCtl
 Scroll @ maxVs CALL SetMaxCtl   
 Scroll @ 0 CALL SetCtlValue 
 0 lastVs !  
 hScroll @ 0 CALL SetMinCtl
 hScroll @ maxHs CALL SetMaxCtl   
 hScroll @ 0 CALL SetCtlValue 
 0 lastHs !  
;


: EditFile   {   | char exitflag --   }
 BEGIN
     Visible?
     IF
      ?TERMINAL IF
 KEY -> char( get the character )
      char 14 = IF
        0 -> exitflag ( if cmd ‘.’ exit )
 ELSE
 char @TEHandle CALL TEKey
 ( else insert )
 1 -> exitflag   ( char )
 THEN
 ELSE
        1 -> exitflag
 ( if no key pressed, keep looping )
      THEN
 
     ELSE
      0 -> exitflag
 ( if window’s been closed, exit )
     THEN
 exitflag ( check exit condition )
 WHILE
     @TEHandle CALL TEIdle
 REPEAT
;
 
 
: Open 
 Pop-Up
 Editor CALL SetPort
    
 TERect TERect CALL TEStyleNew TEHandle ! 
 \ get new style TE record 
 -1 teCROnly @TEHANDLE @ + W! ( no word wrap )
 -1 teCarAct @TEHandle @ + C! ( activate caret )
 -1 @TEHandle call TEAutoView
 \ enable auto scroll

 ( get the first 1K of text )
 0 VIRTUAL 1024 0 @TEHandle TEStylinsert
 0 0 @TEHandle CALL TESetSelect
 15 ( doAll ) myStyle -1 ( redraw) @TEHandle
 call TESetStyle 
 adjustFontMenu
 adjustStyleMenu
 adjustSizeMenu
    
 AdjustTERect  ( initialize the text )
 PortRect Editor + @TEHandle CALL TEUpdate 
 @TEHandle CALL TEDeactivate
 @TEHandle CALL TEActivate

 SetScrollLimits
 Editor CALL DrawControls Editor CALL DrawGrowIcon

 [‘] UPDATE-HANDLER UpdateHook !
 [‘] CONTENT-HANDLER ContentHook !
 [‘] ACTIVATE-HANDLER ActivateHook !    
 [‘] CLOSEBOX-HANDLER CloseBoxHook !  
;
    
 
\ ***** menu handlers *****

: HandleDeskAcc ( item# -  )
 APPLEMENU @ SWAP DESKNAME CALL GETITEM
 DESKNAME CALL OPENDESKACC
 DROP 
;

: DO-APPLE ( item# -  )
 dup 1 = IF
     ( AboutEdit ) ( About Editor ... )
     drop
 ELSE  HandleDeskAcc
 THEN 
;

: NewFile ;
: OpenFile ;
: CloseFile ;
: SaveFile ;
: SaveAs ;
: Revert ;

: DO-FILE ( item# -  )
 CASE
 1 OF NewFile    ENDOF
 2 OF   OpenFile ENDOF
 3 OF   CloseFileENDOF
 4 OF SaveFile   ENDOF
 5 OF SaveAsENDOF
 6 OF RevertENDOF
 ENDCASE 
;

: DO-EDIT ( item# - )
 CASE
 1 OF   ( TEUndo )   ENDOF
 3 OF   @TEHandle CALL TECut  ENDOF
 4 OF @TEHandle CALL TECopy ENDOF
 5 OF @TEHandle CALL TEStylPaste   ENDOF
 6 OF @TEHandle CALL TEDelete ENDOF
 ENDCASE  
;

: DO-Font { item# | fontID - }
 FontMenu @ item# Fontname call getitem
 Fontname ^ fontID call getFNum
 ^ fontID w@ myStyle w! 
 \ put into tsFont field of style record
 1 ( doFont) myStyle -1 ( redraw) @TEHandle
 call TESetStyle
 FontMenu @ currentFont @ 0 check 
 FontMenu @ item# -1 check
 item# currentFont !
;

: Do-Style { item# | facefield -- }
 myStyle tsFace + -> facefield
 item# CASE
 1 OF ( plain text ) 
   0 facefield w!
 ENDOF  

 facefield w@ 
 1 item# 2- scale xor 
 facefield w! \ flip bit
 ENDCASE

 2 ( doFace) myStyle -1 ( redraw) @TEHandle
 call TESetStyle
 adjustStyleMenu
;

 
: Do-Size  ( item# - ) 
 SizeTable + c@
 myStyle tsSize + w!
 4 ( doSize) myStyle -1 ( redraw) @TEHandle
 call TESetStyle
 adjustSizeMenu
;
 
: MBAR-HANDLER  ( item# menuID -  )
 CASE
 APPLEID OF DO-APPLE    ENDOF
 FILEID OF DO-FILE   ENDOF
 EDITID OF DO-EDIT ENDOF
 FontID OF DO-Font ENDOF
 SIZEID OF DO-Size ENDOF
 STYLEIDOF DO-StyleENDOF
 ENDCASE  
 0 CALL HILITEMENU  
;


\ ***** control action routines *****

\ A control action routine specifies what action should take 
\ place WHILE a control is being held down.

: ScrollText  { dv  dh  --   }
 dh dv @TEHandle CALL TEScroll   
;
 
: DO-Scroll { part-code  | ctlvalue  -  }
   part-code
   CASE
      inuparrow OF  Scroll @ CALL GetCtlValue  -> ctlvalue
        ctlvalue 0= NOT 
     IF
        Scroll @ ctlvalue 1- call SetCtlValue
 5 0  ScrollText
     THEN
 ENDOF
 
      indownarrow OF  Scroll @ call GetCtlValue  -> ctlvalue
 ctlvalue maxVs = NOT
     IF
 Scroll @ ctlvalue 1+ call SetCtlValue
 -5 0 ScrollText
     THEN
 ENDOF
 
      inpageup  OF  Scroll @ call GetCtlValue  -> ctlvalue
 ctlvalue 0= NOT 
     IF
 Scroll @ ctlvalue 5 - call SetCtlValue
 25 0  ScrollText
     THEN
 ENDOF
 
      inpagedown OF  Scroll @ call GetCtlValue   -> ctlvalue
 ctlvalue maxVs = NOT
      IF
        Scroll @ ctlvalue 5 + call SetCtlValue
 -25 0  ScrollText   
      THEN
 ENDOF
   ENDCASE  
   Scroll @ call GetCtlValue lastVs ! 
;

: DO-hScroll { part-code  | ctlvalue  -  }
   part-code
   CASE
      inuparrow OF hScroll @ call GetCtlValue  -> ctlvalue
        ctlvalue 0= NOT 
     IF
        hScroll @ ctlvalue 1- call SetCtlValue
 0 5 ScrollText
     THEN
 ENDOF
 
      indownarrow OF hScroll @ call GetCtlValue  -> ctlvalue
 ctlvalue maxHs = NOT
     IF
 hScroll @ ctlvalue 1+ call SetCtlValue
 0 -5 ScrollText
     THEN
 ENDOF
 
      inpageup  OF hScroll @ call GetCtlValue  -> ctlvalue
 ctlvalue 0= NOT 
     IF
 hScroll @ ctlvalue 5 - call SetCtlValue
 0 25 ScrollText
     THEN
 ENDOF
 
      inpagedown OF hScroll @ call GetCtlValue  -> ctlvalue
 ctlvalue maxHs = NOT
      IF
        hScroll @ ctlvalue 5 + call SetCtlValue
 0 -25 ScrollText   
      THEN
 ENDOF
   ENDCASE    
   hScroll @ call GetCtlValue lastHs ! 
;

: ControlAction  ( part-code  control-handle -  )
 CASE
  Scroll @ OF DO-Scroll   ENDOF
 hScroll @ OF DO-hScroll ENDOF
 swap drop
 ENDCASE
;


\ ***** scrollbar thumb control handler *****

: DO-vThumb { | ctlV }
 inThumb = IF
 scroll @ call getCtlValue -> ctlV
 lastVs @ ctlV - 5 * 0 scrollText
 ctlV lastVs !
 THEN
;

: DO-hThumb { | ctlV }
 inThumb = IF
 hscroll @ call getCtlValue -> ctlV
 0 lastHs @ ctlV - 5 * scrollText
 ctlV lastHs !
 THEN 
;
  
: ControlHandler  ( part-code  control-handle -  )
 CASE
  Scroll @ OF DO-vThumb   ENDOF
 hScroll @ OF DO-hThumb  ENDOF
 swap drop
 ENDCASE
;


\ ***** initialization *****

: INIT-MBAR
 EditBar ADD
 EditBar APPLEMENU ADD    
 APPLEMENU @ “drvr call addresmenu
 EditBar FileMenu  ADD
 EditBar EditMenu  ADD
 EditBar FontMenu  ADD  
 Fontmenu @ “font call addresmenu
 Fontmenu @ call countMItems #fonts !
 EditBar SizeMenu  ADD 
 EditBar StyleMenu ADD
;
 
: INIT-TASK
 Editor ADD ( make the Editor window )
 Editor Scroll ADD ( add vertical scroll bar )
 Editor hScroll ADD( add horizontal scroll bar )
 Editor EditTask BUILD 
;
 
: START-TASK
 ACTIVATE 
 [‘] ControlAction CAction !
 [‘] ControlHandler Control-Vector !
 [‘] MBAR-HANDLER MENU-VECTOR !  
 BEGIN
     STANDARD-GETFILE
     IF
 Open
 EditFile
 ShutDown
     THEN
     [‘] RUN-UPDATE UpdateHook !
     [‘] RUN-CONTENT ContentHook !
     [‘] RUN-ACTIVATE ActivateHook !
     [‘] RUN-CLOSEBOX CloseBoxHook !
     SLEEP STATUS W! ( put Editor task to sleep )
     PAUSE( exit this task )
 AGAIN 
;

: INIT-EDIT
 INIT-TASK
 INIT-MBAR
 EditBar EditTask MBAR>TASK 4 myStyle w!     \ default font, Monaco
 0 myStyle 2+ w! \ default face, plain text
 9 myStyle 4 + w! \ default size, 9 point
 0 myStyle 6 + ! \ RGBcolor = ...
 0 myStyle 10 + w! \ ...black 
 4   TERect     W! ( define the text edit rectangle )
 4   TERect 2+  W!
 288 TERect 4 + W!
 503 TERect 6 + W!
 EditTask START-TASK  
;


: EDIT  ( wakes up Editor task )
 EDITTASK @ 
 IFWAKE STATUS TASK-> EditTask W!
 ELSE INIT-EDIT
 THEN
;
 
AAPL
$96.13
Apple Inc.
+0.53
MSFT
$42.86
Microsoft Corpora
-0.30
GOOG
$566.07
Google Inc.
-5.53

MacTech Search:
Community Search:

Software Updates via MacUpdate

Data Rescue 3.2.4 - Recover lost data on...
Data Rescue is a robust and reliable hard-drive recovery solution for your Mac. Recover lost or deleted files, mount corrupted drives, and more -- Data Rescue offers complete relief from crippling... Read more
Adobe Lightroom 5.6 - Import, develop, a...
Adobe Lightroom software helps you bring out the best in your photographs, whether you're perfecting one image, searching for ten, processing hundreds, or organizing thousands. Create incredible... Read more
OneNote 15.2 - Free digital notebook fro...
OneNote is your very own digital notebook. With OneNote, you can capture that flash of genius, that moment of inspiration, or that list of errands that’s too important to forget. Whether you’re at... Read more
iStat Menus 4.22 - Monitor your system r...
iStat Menus lets you monitor your system right from the menubar. Included are 8 menu extras that let you monitor every aspect of your system. Some features: CPU -- Monitor cpu usage. 7 display... Read more
Ember 1.8 - Versatile digital scrapbook....
Ember (formerly LittleSnapper) is your digital scrapbook of things that inspire you: websites, photos, apps or other things. Just drag in images that you want to keep, organize them into relevant... Read more
OmniPlan 2.3.6 - Robust project manageme...
With OmniPlan, you can create logical, manageable project plans with Gantt charts, schedules, summaries, milestones, and critical paths. Break down the tasks needed to make your project a success,... Read more
Command-C 1.1.1 - Clipboard sharing tool...
Command-C is a revolutionary app which makes easy to share your clipboard between iOS and OS X using your local WiFi network, even if the app is not currently opened. Copy anything (text, pictures,... Read more
Knock 1.1.7 - Unlock your Mac by knockin...
Knock is a faster, safer way to sign in. You keep your iPhone with you all the time. Now you can use it as a password. You never have to open the app -- just knock on your phone twice, even when it's... Read more
Mellel 3.3.6 - Powerful word processor w...
Mellel is the leading word processor for OS X and has been widely considered the industry standard since its inception. Mellel focuses on writers and scholars for technical writing and multilingual... Read more
LibreOffice 4.3.0.4 - Free Open Source o...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more

Latest Forum Discussions

See All

Bio Inc. is $0.99 for the Weekend, Recei...
Bio Inc. is $0.99 for the Weekend, Receives Small Update Posted by Ellis Spice on August 1st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Happy 7th Birthday Readdle! Thank You fo...
Happy 7th Birthday Readdle! | Read more »
Sharknado: The Video Game Review
Sharknado: The Video Game Review By Lee Hamlet on August 1st, 2014 Our Rating: :: SHARKNA-DON'TUniversal App - Designed for iPhone and iPad Sharknado: The Video Game brings the craziness of the movies to iOS, though it quickly... | Read more »
Clima (Weather)
Clima 1.0 Device: iOS iPhone Category: Weather Price: $.99, Version: 1.0 (iTunes) Description: Clima show you all weather information, just beautifully simple. A series of color bars can tell you at a glance exactly current... | Read more »
Sticky Soccer Review
Sticky Soccer Review By Andrew Fisher on August 1st, 2014 Our Rating: :: STICK THIS GAMEUniversal App - Designed for iPhone and iPad Sticky Soccer puts too much emphasis on the ‘sticky’ and not enough on the ‘Soccer’ or ‘Fun’.   | Read more »
Graphics-less Apocalyptic Adventure A Da...
Graphics-less Apocalyptic Adventure A Dark Room Goes Free for a Limited Time Posted by Rob Rich on August 1st, 2014 [ permalink ] | Read more »
Fraud Tycoon Review
Fraud Tycoon Review By Rob Thomas on August 1st, 2014 Our Rating: :: UNHEALTHY CREDITUniversal App - Designed for iPhone and iPad Fraud Tycoon is a half-baked, messy, promotional tie-in that does their sponsor no favors whatsoever... | Read more »
Guardians of the Galaxy: The Universal W...
Guardians of the Galaxy: The Universal Weapon is on Sale for the Weekend Posted by Rob Rich on August 1st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Mister Beam Review
Mister Beam Review By Jordan Minor on August 1st, 2014 Our Rating: :: ILLUMINATINGUniversal App - Designed for iPhone and iPad Mister Beam’s puzzles are great. But its platforming? Not so much.   | Read more »
Hook Some More Fun With MapHook’s New Up...
Hook Some More Fun With MapHook’s New Update Posted by Jessica Fisher on August 1st, 2014 [ permalink ] iPhone App - Designed for the iPhone, compatible with the iPad | Read more »

Price Scanner via MacPrices.net

13-inch MacBook Airs on sale for $100 off MSR...
B&H Photo has the new 2014 13″ MacBook Airs on sale $100 off MSRP. Shipping is free, and B&H charges NY sales tax only. They also include free copies of Parallels Desktop and LoJack for... Read more
16GB iPad Air on sale for $399, save $100
Best Buy is offering the 16GB WiFi iPad Air for $399.99 on their online store for a limited time. Their price is $100 off MSRP. Choose free shipping or free store pickup (if available). Price is for... Read more
All Over For Tablets Or Just A Maturing, Evol...
CNN’s David Goldman weighs in on tablet sector doom and gloom, asking rhetorically: “Is this the beginning of the end for the tablet?” Answering that, he contends that hysteria and panic are... Read more
Letterspace 1.0.1 – New Free iOS Text Editor...
Bangkok, Thailand based independent developer Sittipon Simasanti has released Letterspace, a new text editor for iPhone, iPad, and iPod touch devices. Letterspace is a note taking app with an... Read more
Save up to $130 on an iPad mini with Apple re...
The Apple Store has Certified Refurbished 2nd generation iPad minis with Retina Displays available for up to $130 off the cost of new models, starting at $339. Apple’s one-year warranty is included... Read more
iPad Cannibalization Threat “Overblown”
Seeking Alpha’s Kevin Greenhalgh observes that while many commentators think Apple’s forthcoming 5.5-inch panel iPhone 6 will cannibalize iPad sales, in his estimation, these concerns are being... Read more
Primate Labs Releases July 2014 MacBook Pro P...
Primate Labs’ John Poole has posted Geekbench 3 results for most of the new MacBook Pro models that Apple released on Tuesday. Poole observes that overall performance improvements for the new MacBook... Read more
Apple Re-Releases Bugfixed MacBook Air EFI Fi...
Apple has posted a bugfixed version EFI Firmware Update 2.9 a for MacBook Air (Mid 2011) models. The update addresses an issue where systems may take longer to wake from sleep than expected, and... Read more
Save $50 on the 2.5GHz Mac mini, plus free sh...
B&H Photo has the 2.5GHz Mac mini on sale for $549.99 including free shipping. That’s $50 off MSRP, and B&H will also include a free copy of Parallels Desktop software. NY sales tax only. Read more
Save up to $140 on an iPad Air with Apple ref...
Apple is offering Certified Refurbished iPad Airs for up to $140 off MSRP. Apple’s one-year warranty is included with each model, and shipping is free. Stock tends to come and go with some of these... Read more

Jobs Board

Position Opening at *Apple* - Apple (United...
**Job Summary** The Apple Store is a retail environment like no other - uniquely focused on delivering amazing customer experiences. As an Expert, you introduce people Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** At the Apple Store, you connect business professionals and entrepreneurs with the tools they need in order to put Apple solutions to work in their Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Sr. Product Leader, *Apple* Store Apps - Ap...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
Sr Software Lead Engineer, *Apple* Online S...
Sr Software Lead Engineer, Apple Online Store Publishing Systems Keywords: Company: Apple Job Code: E3PCAK8MgYYkw Location (City or ZIP): Santa Clara Status: Full Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.