ðÖhSyntax10.Scn.FntUËÿÿÿ€8ÀÔFoldElemsNew#Syntax10.Scn.Fnt END NoTreeNotify;ÿÿÿÿ€8ÀÔIÌÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt END NoTxtNotify;ÿÿÿÿ€8ÀÔWWÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt‡‡ VAR msg: UpdateMsg; BEGIN msg.root:= root; msg.new:= new; msg.old:= old; msg.id := op; Viewers.Broadcast(msg) END NotifyDisplay;ÿÿÿÿ€8ÀÔMÇþÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR r: Texts.Reader; BEGIN Texts.OpenReader(r, txt, Texts.ElemPos(e)); Texts.ReadElem(r); WHILE ~(r.elem IS FoldElems.Elem) DO Texts.ReadElem(r); END; e.exp:= ~e.exp; FoldElems.Switch(r.elem(FoldElems.Elem)); txt.notify(txt, Texts.replace, 0, txt.len); END Switch;ÿÿÿÿ€8ÀÔDÿÿÿ€8ÀÔ#Syntax10.Scn.FntÚÚ VAR r: Texts.Reader; BEGIN Texts.OpenReader(r, txt, Texts.ElemPos(e)); Texts.ReadElem(r); WHILE ~(r.elem IS FoldElems.Elem) DO Texts.ReadElem(r); END; RETURN FoldElems.Twin(r.elem(FoldElems.Elem)); END Twin;ÿÿÿÿ€8ÀÔ2Xýÿÿ€8ÀÔ#Syntax10.Scn.Fnt†† VAR r: Texts.Reader; e: FolderElem; twin: FoldElems.Elem; expand: BOOLEAN; orgNotify: Texts.Notifier; BEGIN orgNotify:= f.text.notify; f.text.notify:= NoTxtNotify; Texts.OpenReader(r, f.text, 0); Texts.ReadElem(r); expand:= t = f.tree; twin:= NIL; WHILE (r.elem # NIL) & (r.elem # twin) DO IF r.elem IS FolderElem THEN e:= r.elem(FolderElem); IF ~expand & (e.node = t) THEN expand:= TRUE; twin:= Twin(f.text, e); END; IF expand & ~e.exp THEN Switch(f.text, e); END; END; Texts.ReadElem(r); END; f.text.notify:= orgNotify; f.text.notify(f.text, Texts.replace, 0, f.text.len); END ExpandAll;ÿÿÿÿ€8ÀÔ4äûÿÿ€8ÀÔ#Syntax10.Scn.Fntúú VAR r: Texts.Reader; e, end: FolderElem; twin: FoldElems.Elem; collapse: BOOLEAN; orgNotify: Texts.Notifier; BEGIN orgNotify:= f.text.notify; f.text.notify:= NoTxtNotify; Texts.OpenReader(r, f.text, 0); Texts.ReadElem(r); IF t # f.tree THEN (* sub-tree *) end:= NIL; WHILE (r.elem # NIL) & (end = NIL) DO (* search for folder with tree t *) IF (r.elem IS FolderElem) & (r.elem(FolderElem).node = t) THEN end:= r.elem(FolderElem); END; Texts.ReadElem(r); END; IF end = NIL THEN RETURN; END; (* not found *) twin:= Twin(f.text, end); END; collapse:= t = f.tree; Texts.OpenReader(r, f.text,f.text.len); Texts.ReadPrevElem(r); WHILE r.elem # end DO IF r.elem IS FolderElem THEN e:= r.elem(FolderElem); IF collapse & e.exp THEN Switch(f.text, e); END; END; IF ~collapse THEN collapse:= r.elem = twin; END; Texts.ReadPrevElem(r); END; f.text.notify:= orgNotify; f.text.notify(f.text, Texts.replace, 0, f.text.len); END CollapseAll;ÿÿÿÿ€8ÀÔAüÿÿ€8ÀÔ?Syntax10.Scn.FntG < &¾ VAR e1: Elem; r: Files.Rider; maxW: LONGINT; BEGIN WITH e: Elem DO WITH msg: Texts.CopyMsg DO IF msg.e = NIL THEN NEW(e1); END; Texts.CopyElem(e, e1); e1.id:= e.id; msg.e := e1; | msg: TextFrames.DisplayMsg DO IF msg.prepare THEN e.W:= W * Unit; e.H:= H * Unit; ELSE Display.CopyPattern(hCol, treeIcons[e.id], msg.X0, msg.Y0, Display.paint); END; | msg: Texts.FileMsg DO IF msg.id = Texts.load THEN Files.ReadInt(msg.r, e.id); ELSE Files.WriteInt(msg.r, e.id); END; | msg: Texts.IdentifyMsg DO msg.mod:= "TreeFrames"; msg.proc:= "AllocTreeElem"; ELSE END; | e: FoldElems.Elem DO WITH msg: Texts.IdentifyMsg DO msg.mod:= "TreeFrames"; msg.proc:= "AllocFoldElem"; | msg: Texts.FileMsg DO FoldElems.FoldHandler(e, msg); IF msg.id = Texts.load THEN e.visible:= FALSE; END; ELSE FoldElems.FoldHandler(e, msg); END; ELSE END END ElemHandle;ÿÿÿÿ€8ÀÔEÁôÿÿ€8ÀÔ?Syntax10.Scn.Fnt… ± ³ VAR ne: NodeElem; fe: FolderElem; neutralize: Oberon.ControlMsg; selectMsg: SelectMsg; keys: SET; x, y: INTEGER; BEGIN WITH e: FolderElem DO WITH msg: TextFrames.TrackMsg DO IF (middleKey IN msg.keys) & ((e.id = aFolder) OR (e.id = lastFolder)) THEN neutralize.id:= Oberon.neutralize; msg.frame.handle(msg.frame, neutralize); REPEAT Input.Mouse(keys, x, y); msg.keys:= msg.keys + keys; Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, x, y); UNTIL keys = {}; IF msg.keys = {middleKey} THEN IF e.exp THEN Display.CopyPattern(Display.white, foldDescr[minus], msg.X0 + 3, msg.Y0 + 5, Display.invert); Display.CopyPattern(Display.white, foldDescr[plus], msg.X0 + 3, msg.Y0 + 5, Display.invert); ELSE Display.CopyPattern(Display.white, foldDescr[plus], msg.X0 + 3, msg.Y0 + 5, Display.invert); Display.CopyPattern(Display.white, foldDescr[minus], msg.X0 + 3, msg.Y0 + 5, Display.invert); END; Switch(msg.frame(TextFrames.Frame).text, e); END END; | msg: TextFrames.DisplayMsg DO IF msg.prepare THEN IF e.id = invisible THEN e.W:= 1; ELSE e.W:= W * Unit; END; e.H:= H * Unit; ELSIF e.id # invisible THEN Display.CopyPattern(hCol, treeIcons[e.id], msg.X0, msg.Y0, Display.paint); IF (e.id = aFolder) OR (e.id = lastFolder) THEN IF e.exp THEN Display.CopyPattern(15, foldDescr[minus], msg.X0 + 3, msg.Y0 + 5, Display.paint); ELSE Display.CopyPattern(15, foldDescr[plus], msg.X0 + 3, msg.Y0 + 5, Display.paint); END; END; END; | msg: Texts.CopyMsg DO IF msg.e = NIL THEN NEW(fe); END; Texts.CopyElem(e, fe); fe.id:= e.id; fe.exp:= e.exp; fe.node:= e.node; msg.e:= fe; | msg: Texts.IdentifyMsg DO msg.mod:= "TreeFrames"; msg.proc:= "AllocFolderElem"; | msg: Texts.FileMsg DO IF msg.id = Texts.load THEN Files.ReadInt(msg.r, e.id); Files.ReadBool(msg.r, e.exp); ELSE Files.WriteInt(msg.r, e.id); Files.WriteBool(msg.r, e.exp); END; ELSE END; | e: NodeElem DO WITH msg: Texts.IdentifyMsg DO msg.mod:= "TreeFrames"; msg.proc:= "AllocNodeElem"; | msg: TextFrames.DisplayMsg DO IF msg.prepare THEN IF e.id = invisible THEN e.W:= 1; ELSE e.W:= W * Unit; END; e.H:= H * Unit; ELSIF e.id # invisible THEN Display.CopyPattern(hCol, treeIcons[e.id], msg.X0, msg.Y0, Display.paint); END; | msg: Texts.FileMsg DO IF msg.id = Texts.load THEN Files.ReadInt(msg.r, e.id); ELSE Files.WriteInt(msg.r, e.id); END; | msg: Texts.CopyMsg DO IF msg.e = NIL THEN NEW(ne); END; Texts.CopyElem(e, ne); ne.id:= e.id; ne.node:= e.node; msg.e:= ne; ELSE END; ELSE END; END NodeElemHandle;ÿÿÿÿ€8ÀÔ.eÿÿÿ€8ÀÔ#Syntax10.Scn.Fntyy BEGIN e.handle:= ElemHandle; e.W:= W; e.H:= H; IF pl THEN e.id:= plain; ELSE e.id:= branch; END; END InitTreeElem;ÿÿÿÿ€8ÀÔJQÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt BEGIN e.handle:= NodeElemHandle; e.W:= W; e.H:= H; e.node:= t; IF last THEN e.id:= lastNode; ELSE e.id:= aNode; END; END InitNodeElem;ÿÿÿÿ€8ÀÔX\ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt‚‚ BEGIN InitNodeElem(last, t, e); IF last THEN e.id:= lastFolder; ELSE e.id:= aFolder; END; e.exp:= exp; END InitFolderElem;ÿÿÿÿ€8ÀÔ/ñþÿÿ€8ÀÔ#Syntax10.Scn.Fntíí VAR te: Elem; BEGIN IF node.parent = NIL THEN RETURN END; DrawBranch(node.parent); NEW(te); IF node.isLastChild() THEN InitTreeElem(TRUE, te); ELSE InitTreeElem(FALSE, te); END; Texts.WriteElem(w, te); END DrawBranch;ÿÿÿÿ€8ÀÔ]Ðüÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR copyMsg: Texts.CopyMsg; t: Trees.Tree; BEGIN IF tn IS Trees.Tree THEN t:= tn(Trees.Tree); IF empty & (t.count = 0) THEN IF tn.isLastChild() THEN e.id:= lastNode;Texts.WriteElem(w, e); ELSE e.id:= aNode; Texts.WriteElem(w, e); END; ELSE IF tn.isLastChild() THEN e.id:= lastFolder; Texts.WriteElem(w, e); ELSE e.id:= aFolder;Texts.WriteElem(w, e); END; END; ELSE IF tn.isLastChild() THEN e.id:= lastNode;Texts.WriteElem(w, e); ELSE e.id:= aNode; Texts.WriteElem(w, e); END; END; IF tn.elem # NIL THEN tn.elem.handle(tn.elem, copyMsg); Texts.WriteElem(w, copyMsg.e); END; IF tn.name = "" THEN Texts.WriteString(w, "_"); (* necessary to find node.name in text *) ELSE Texts.WriteString(w, tn.name); END; END PrintNode;ÿÿÿÿ€8ÀÔ4Óÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt n: SHORTINTÿÿÿÿ€8ÀÔšøÿÿ€8ÀÔ Syntax10.Scn.Fnt“Bÿÿÿ€8ÀÔFoldElemsNew#Syntax10.Scn.Fntœœ FOR i:= 1 TO n DO DrawBranch(tn.parent); NEW(te); InitTreeElem(FALSE, te); Texts.WriteElem(w, te); Texts.WriteLn(w); END; ÿÿÿÿ€8ÀÔKÿÿÿ€8ÀÔ#Syntax10.Scn.FntÃà e.mode:= FoldElems.expLeft; e.W:= FoldElems.elemW; e.H:= FoldElems.elemH; e.handle:= ElemHandle; NEW(e.hidden); Texts.OpenBuf(e.hidden); e.visible:= FALSE; Texts.WriteElem(w, e);ÿÿÿÿ€8ÀÔ4Eÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt™™ e.mode:= FoldElems.expRight; e.W:= FoldElems.elemW; e.H:= FoldElems.elemH; e.handle:= ElemHandle; e.visible:= FALSE; Texts.WriteElem(w, e);ÿÿÿÿ€8ÀÔŒBÿÿÿ€8ÀÔ#Syntax10.Scn.Fntœœ FOR i:= 1 TO n DO DrawBranch(tn.parent); NEW(te); InitTreeElem(FALSE, te); Texts.WriteElem(w, te); Texts.WriteLn(w); END; ÿÿÿÿ€8ÀÔe^ VAR tn: Trees.TreeNode; en: Trees.Enumerator; e: FoldElems.Elem; ne: NodeElem; fe: FolderElem; te: Elem; i: SHORTINT; BEGIN en:= tree.enumerate(); WHILE en.hasMoreElems DO tn:= en.nextElem(); IF tn IS Trees.Tree THEN NEW(e); NEW(fe); InitFolderElem(FALSE, tn(Trees.Tree), TRUE, fe); IF fr.neHandler # NIL THEN fe.handle:= fr.neHandler; END; Texts.WriteLn(w); (* if maxHeight > H *) DrawBranch(tn.parent); PrintNode(w, tn, fe, fr.showEmptyTr); (* left FoldElem *) PrintTree(fr, tn(Trees.Tree), n); NEW(e); (* right FoldElem *) ELSE NEW(ne); InitNodeElem(FALSE, tn, ne); IF fr.neHandler # NIL THEN ne.handle:= fr.neHandler; END; Texts.WriteLn(w); (* if maxHeight > H *) DrawBranch(tn.parent); PrintNode(w, tn, ne, fr.showEmptyTr); END; END; END PrintTree;ÿÿÿÿ€8ÀÔ)5þÿÿ€8ÀÔ#Syntax10.Scn.Fnt©© VAR copyMsg: Texts.CopyMsg; ne: NodeElem; BEGIN Texts.OpenWriter(w); NEW(ne); InitNodeElem(FALSE, fr.tree,ne); ne.id:= invisible; Texts.WriteElem(w, ne); IF fr.tree.elem # NIL THEN fr.tree.elem.handle(fr.tree.elem, copyMsg); Texts.WriteElem(w, copyMsg.e); END; Texts.WriteString(w, fr.tree.name); PrintTree(fr, fr.tree, (fr.maxH - 1) DIV H); Texts.Append(fr.text, w.buf); END CopyTreeToText;ÿÿÿÿ€8ÀÔzÿÿÿ€8ÀÔ#Syntax10.Scn.Fntdd VAR e: FoldElems.Elem; BEGIN NEW(e); e.handle:= ElemHandle; Texts.new:= e; END AllocFoldElem;ÿÿÿÿ€8ÀÔnÿÿÿ€8ÀÔ#Syntax10.Scn.Fntpp VAR e: FolderElem; BEGIN NEW(e); InitFolderElem(FALSE, NIL, TRUE, e); Texts.new:= e; END AllocFolderElem;ÿÿÿÿ€8ÀÔzÿÿÿ€8ÀÔ#Syntax10.Scn.Fntdd VAR e: NodeElem; BEGIN NEW(e); InitNodeElem(FALSE, NIL, e); Texts.new:= e; END AllocNodeElem;ÿÿÿÿ€8ÀÔ„ÿÿÿ€8ÀÔ#Syntax10.Scn.FntZZ VAR e: Elem; BEGIN NEW(e); InitTreeElem(TRUE, e); Texts.new:= e; END AllocTreeElem;ÿÿÿÿ€8ÀÔ<_þÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR end: INTEGER; r: Texts.Reader; ch: CHAR; endFound: BOOLEAN; BEGIN end:= 0; endFound:= FALSE; Texts.OpenReader(r, txt, pos); Texts.Read(r, ch); WHILE ~endFound DO endFound:= (ch = CR) OR (ch = LF) OR ((r.elem # NIL) & (r.elem IS FoldElems.Elem)); IF ~endFound THEN Texts.Read(r, ch); INC(end); END; END; Texts.Delete(txt, pos, pos + end); END DeleteNodeDesc;ÿÿÿÿ€8ÀÔ’Åÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt BEGIN END InsertNode; ÿÿÿÿ€8ÀÔV ýÿÿ€8ÀÔ#Syntax10.Scn.Fnt¾¾ VAR isLast: BOOLEAN; cnt: INTEGER; r: Texts.Reader; BEGIN DeleteNodeDesc(f.text, pos); isLast:= ne.node.isLastChild(); (* IF isLast THEN ne.node:= ne.node.parent; END;*) WITH ne: FolderElem DO IF ne.exp THEN Switch(f.text, ne); END; Texts.Delete(f.text, pos, pos + 2); ELSE END; (* Texts.OpenReader(r, f.text, pos); Texts.ReadPrevElem(r); cnt:= 0; WHILE (r.elem # NIL) & (r.elem IS Elem) DO Texts.ReadPrevElem(r); INC(cnt); END; Out.Int(cnt, 5); pos:= pos - cnt; Texts.Delete(f.text, pos, pos + cnt); *) (* IF isLast THEN PrintTree(f, ne.node.parent, (f.maxH - 1) DIV H); Texts.Insert(f.text, pos, w.buf); pos:= pos + w.buf.len; END; *) END DeleteNode;ÿÿÿÿ€8ÀÔXÅÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt BEGIN END ReplaceNode;ÿÿÿÿ€8ÀÔWëþÿÿ€8ÀÔ#Syntax10.Scn.Fntóó VAR copyMsg: Texts.CopyMsg; w: Texts.Writer; BEGIN DeleteNodeDesc(f.text, pos); ne.handle(ne, copyMsg); Texts.OpenWriter(w); PrintNode(w, n, copyMsg.e(NodeElem), f.showEmptyTr); Texts.Insert(f.text, pos, w.buf); END ChangeNode;ÿÿÿÿ€8ÀÔGgüÿÿ€8ÀÔ#Syntax10.Scn.Fntww VAR oldNotifier: Texts.Notifier; r: Texts.Reader; found: BOOLEAN; pos: LONGINT; BEGIN oldNotifier:= f.text.notify; f.text.notify:= NoTxtNotify; FoldElems.ExpandAll(f.text, 0, TRUE); Texts.OpenReader(r, f.text, 0); Texts.ReadElem(r); found:= FALSE; IF upd = NIL THEN Texts.Delete(f.text, 0, f.text.len); CopyTreeToText(f); CollapseAll(f.tree, f); ELSE WHILE (r.elem # NIL) & ~found DO found:= (r.elem IS NodeElem) & (r.elem(NodeElem).node = msg.old); IF found THEN pos:= Texts.Pos(r) - 1; upd(f, r.elem(NodeElem), pos, msg.old); END; Texts.ReadElem(r); END; END; FoldElems.CollapseAll(f.text, {FoldElems.tempLeft}); f.text.notify:= oldNotifier; (* notify display *) IF msg.id = 3 THEN msg.id:= 0; ELSIF msg.id = 4 THEN msg.id:= 2; END; f.text.notify(f.text, msg.id, 0, f.text.len); END UpdateNodeElem;ÿÿÿÿ€8ÀÔ9Ÿþÿÿ€8ÀÔ#Syntax10.Scn.Fnt?? VAR loc: TextFrames.Location; r: Texts.Reader; BEGIN TextFrames.LocateLine(f, y, loc); Texts.OpenReader(r, f.text, loc.pos); Texts.ReadElem(r); WHILE (r.elem # NIL) & ~(r.elem IS NodeElem) DO Texts.ReadElem(r); END; IF r.elem # NIL THEN RETURN r.elem(NodeElem); ELSE RETURN NIL END; END GetNodeElem;ÿÿÿÿ€8ÀÔ/Qþÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR loc: TextFrames.Location; x: INTEGER; BEGIN IF f.drawBorder & (f.txtF # NIL) THEN TextFrames.LocatePos(f, f.txtF.beg, loc); x:= loc.x; TextFrames.LocatePos(f, f.txtF.beg + 1, loc); TextFrames.LocateWord(f, loc.x, loc.y, loc); loc.x:= x; GUtils.Frame(f, Display.white, loc.x - 3, loc.y, loc.dx + 6, f.maxH + 2, GUtils.Unit(1, FALSE), id); END; END DrawBorder;ÿÿÿÿ€8ÀÔ xýÿÿ€8ÀÔ#Syntax10.Scn.Fntff VAR r: Texts.Reader; i: SHORTINT; name: ARRAY Trees.MaxNameLength OF CHAR; BEGIN IF f.hasSel THEN TextFrames.RemoveSelection(f); END; IF (f.txtF # NIL) & ~f.txtF.noNeutralize THEN f.txtF.noNeutralize:= TRUE; TextFrames.RemoveCaret(f); DrawBorder(f, Display.paint); DrawBorder(f, Display.invert); Texts.OpenReader(r, f.text, f.txtF.beg); i:= 0; WHILE i < f.txtF.txtLen DO Texts.Read(r, name[i]); INC(i); END; NotifyDisplay(f.tree, f.txtF.node, f.txtF.node, Trees.change); (* refresh *) IF name # "" THEN f.txtF.node.setName(name); END; f.txtF:= NIL; END; END Defocus;ÿÿÿÿ€8ÀÔ.±ûÿÿ€8ÀÔ#Syntax10.Scn.Fnt-- VAR r: Texts.Reader; ch: CHAR; loc: TextFrames.Location; i: SHORTINT; keys: SET; x: INTEGER; edit: EditField; BEGIN IF ~f.editable THEN RETURN; END; Oberon.PassFocus(Viewers.This(f.X, f.Y)); (* defocus this frame, if focused! *) TextFrames.LocateLine(f, y, loc); Texts.OpenReader(r, f.text, loc.pos); Texts.Read(r, ch); NEW(edit); edit.beg:= loc.pos; WHILE r.elem # NIL DO IF r.elem IS NodeElem THEN edit.node:= r.elem(NodeElem).node; END; Texts.Read(r, ch); INC(edit.beg); END; IF (edit.node = NIL) OR (edit.node = f.tree) THEN (* empty lines and root are not editable *) f.txtF:= NIL; RETURN; END; f.txtF:= edit; TextFrames.SetCaret(f, f.txtF.beg); i:= 0; WHILE f.txtF.node.name[i] # 0X DO INC(i); END; f.txtF.txtLen:= i; TextFrames.SetSelection(f, f.txtF.beg, f.txtF.beg + f.txtF.txtLen); f.txtF.curPos:= 0; f.txtF.noNeutralize:= FALSE; REPEAT Input.Mouse(keys, x, y); Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, x, y); UNTIL keys = {}; DrawBorder(f, Display.paint); END EditLine;ÿÿÿÿ€8ÀÔ??÷ÿÿ€8ÀÔ#Syntax10.Scn.FntŸŸ BEGIN IF (msg.id # Oberon.consume) OR (f.txtF = NIL) THEN RETURN; END; f.txtF.noNeutralize:= TRUE; CASE msg.ch OF | 9X, CR, LF, 0C5X, 0C6X, 0C1X, 0C2X: (* TAB, CR, LF, PGUP, PGDN, CRSU, CRSD *) f.txtF.noNeutralize:= FALSE; Defocus(f); | 0A1X: (* DELRIGHT *) DrawBorder(f, Display.invert); IF f.hasSel THEN Texts.Delete(f.text, f.selbeg.pos, f.selend.pos); TextFrames.SetCaret(f, f.selbeg.pos); TextFrames.RemoveSelection(f); DrawBorder(f, Display.paint); f.txtF.txtLen:= 0; ELSIF f.txtF.curPos < f.txtF.txtLen THEN SuperHandle(f, msg); DEC(f.txtF.txtLen); END; DrawBorder(f, Display.paint); | 0C4X: (* CRSL *) IF f.hasSel THEN TextFrames.RemoveSelection(f); END; IF f.txtF.curPos > 0 THEN SuperHandle(f, msg); DEC(f.txtF.curPos); END; DrawBorder(f, Display.paint); | 0C3X: (* CRSR *) IF f.hasSel THEN TextFrames.RemoveSelection(f); END; IF f.txtF.curPos < f.txtF.txtLen THEN SuperHandle(f, msg); INC(f.txtF.curPos); END; DrawBorder(f, Display.paint); | 0C7X: (* END *) IF f.hasSel THEN TextFrames.RemoveSelection(f); END; msg.ch:= 0C3X; WHILE f.txtF.curPos < f.txtF.txtLen DO SuperHandle(f, msg); INC(f.txtF.curPos); END; DrawBorder(f, Display.paint); | 0C8X: (* HOME *) IF f.hasSel THEN TextFrames.RemoveSelection(f); DrawBorder(f, Display.paint); ELSE msg.ch:= 0C4X; WHILE f.txtF.curPos > 0 DO SuperHandle(f, msg); DEC(f.txtF.curPos); END; END; DrawBorder(f, Display.paint); | 7FX: (* DEL (back space) *) DrawBorder(f, Display.invert); IF f.hasSel THEN Texts.Delete(f.text, f.selbeg.pos, f.selend.pos); TextFrames.SetCaret(f, f.selbeg.pos); TextFrames.RemoveSelection(f); f.txtF.txtLen:= 0; ELSIF f.txtF.curPos > 0 THEN SuperHandle(f, msg); DEC(f.txtF.curPos); DEC(f.txtF.txtLen); END; DrawBorder(f, Display.paint); ELSE IF f.txtF.txtLen < (Trees.MaxNameLength - 1) THEN DrawBorder(f, Display.invert); SuperHandle(f, msg); DrawBorder(f, Display.paint); INC(f.txtF.curPos); INC(f.txtF.txtLen); END; END; IF f.txtF # NIL THEN f.txtF.noNeutralize:= FALSE; END; END KeyboardHandler;ÿÿÿÿ€8ÀÔ8 ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt¾¾ BEGIN IF x + w > F.X + F.W - F.right THEN w := F.X + F.W - F.right - x END ; IF y >= F.Y + F.bot THEN Display.ReplConst(Display.white, x, y, w, h, Display.invert) END END InvertRect;*ÿÿÿÿ€8ÀÔ#%þÿÿ€8ÀÔ#Syntax10.Scn.Fnt¹¹ BEGIN DF.handle := SF.handle; DF.text := SF.text; DF.org := SF.org; DF.col := SF.col; DF.left := SF.left; DF.right := SF.right; DF.top := SF.top; DF.bot := SF.bot; DF.barW := SF.barW; DF.hasCar := FALSE; DF.hasSel := FALSE; DF.showsParcs := SF.showsParcs; DF.focus := NIL; DF.tree:= SF.tree; DF.editable:= SF.editable; DF.showEmptyTr:= SF.showEmptyTr; DF.txtF:= NIL; DF.neHandler:= SF.neHandler; DF.maxH:= SF.maxH; END Copy;ÿÿÿÿ€8ÀÔCÈöÿÿ€8ÀÔ1Syntax10.Scn.Fnt¤ \ VAR pos: LONGINT; r: Texts.Reader; ch: CHAR; keys: SET; x, y: INTEGER; selectMsg: SelectMsg; loc: TextFrames.Location; f1: Frame; ne: NodeElem; BEGIN WITH f: Frame DO WITH msg: UpdateMsg DO Defocus(f); IF msg.root = f.tree THEN IF msg.id = Trees.change THEN UpdateNodeElem(f, msg, ChangeNode); (* ELSIF msg.id = Trees.delete THEN UpdateNodeElem(f, msg, DeleteNode); ELSIF msg.id = Trees.insert THEN UpdateNodeElem(f, msg, InsertNode); ELSIF msg.id = Trees.remove THEN UpdateNodeElem(f, msg, RemoveNode); *) ELSE UpdateNodeElem(f, msg, NIL); END; END; | msg: Oberon.InputMsg DO IF msg.id = Oberon.track THEN IF (msg.X > f.X + f.barW) & (msg.X < f.X + f.W) THEN (* inside text-area *) IF middleKey IN msg.keys THEN (* select node *) Defocus(f); TextFrames.LocateWord(f, msg.X, msg.Y, loc); IF loc.dx = 0 THEN (* no word selected *) SuperHandle(f, msg); ELSE InvertRect(f, loc.x, loc.y, loc.dx, 2); REPEAT Input.Mouse(keys, x, y); msg.keys:= msg.keys + keys; Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, x, y); UNTIL keys={}; InvertRect(f, loc.x, loc.y, loc.dx, 2); (* send selectMsg *) selectMsg.root:= f.tree; ne:= GetNodeElem(f, msg.Y); selectMsg.node:= ne.node; selectMsg.time:= Oberon.Time(); Viewers.Broadcast(selectMsg); END; ELSIF leftKey IN msg.keys THEN (* edit node *) Defocus(f); pos:= TextFrames.Pos(f, msg.X, msg.Y); Texts.OpenReader(r, f.text, pos); Texts.Read(r, ch); IF r.elem = NIL THEN EditLine(f, msg.Y); END; ELSIF rightKey IN msg.keys THEN Defocus(f); END; ELSE (* scroll-bar *) SuperHandle(f, msg); END; ELSE (* own keyboard handler *); KeyboardHandler(f, msg); END; | msg: Oberon.ControlMsg DO IF (f.txtF # NIL) & ((msg.id = Oberon.defocus) OR (msg.id = Oberon.neutralize)) THEN Defocus(f); END; SuperHandle(f, msg); | msg: Oberon.CopyMsg DO IF msg.F = NIL THEN NEW(f1); msg.F := f1 END ; Copy(f, msg.F(Frame)); ELSE SuperHandle(f, msg); END; ELSE SuperHandle(f, msg); END; END Handle;ÿÿÿÿ€8ÀÔ/ÿÿÿ€8ÀÔ#Syntax10.Scn.FntÅÅ BEGIN TextFrames.Open(F, TextFrames.Text(""), 0); F.handle:= Handle; F.tree:= T; F.maxH:= 16; F.editable:= FALSE; F.drawBorder:= FALSE; CopyTreeToText(F); CollapseAll(T, F); END Open;ÿÿÿÿ€8ÀÔ-‡ÿÿÿ€8ÀÔ#Syntax10.Scn.FntWW VAR frame: Frame; BEGIN NEW(frame); Open(frame, t); RETURN frame END NewTree;ÿÿÿÿ€8ÀÔGjÿÿÿ€8ÀÔ#Syntax10.Scn.Fnttt VAR frame: Frame; BEGIN NEW(frame); frame.neHandler:= h; Open(frame, t); RETURN frame; END NewTreewHandler;ÿÿÿÿ€8ÀÔ"tÿÿÿ€8ÀÔ#Syntax10.Scn.Fntjj VAR t: Trees.Tree; BEGIN NEW(t); Trees.InitTree(t); t.notify:= NotifyDisplay; RETURN t; END Tree;ÿÿÿÿ€8ÀÔIœÿÿÿ€8ÀÔ#Syntax10.Scn.FntBB BEGIN RETURN TextFrames.NewMenu(name, commands); END NewMenu;ÿÿÿÿ€8ÀÔðóÿÿ€8ÀÔ¬ Syntax10.Scn.Fnt?çþÿÿ€8ÀÔFoldElemsNew#Syntax10.Scn.Fnt÷÷ img[16]:= {}; img[15]:= {}; img[14]:= {}; img[13]:= {}; img[12]:= {}; img[11]:= {}; img[10]:= {}; img[9]:= {}; img[8]:= {}; img[7]:= {}; img[6]:= {}; img[5]:= {}; img[4]:= {}; img[3]:= {}; img[2]:= {}; img[1]:= {}; ÿÿÿÿ€8ÀÔ5ßþÿÿ€8ÀÔ#Syntax10.Scn.Fntÿÿ img[16]:= {5}; img[15]:= {}; img[14]:= {5}; img[13]:= {}; img[12]:= {5}; img[11]:= {}; img[10]:= {5}; img[9]:= {}; img[8]:= {5}; img[7]:= {}; img[6]:= {5}; img[5]:= {}; img[4]:= {5}; img[3]:= {}; img[2]:= {5}; img[1]:= {}; ÿÿÿÿ€8ÀÔ5Íþÿÿ€8ÀÔ#Syntax10.Scn.Fnt img[16]:= {5}; img[15]:= {}; img[14]:= {5}; img[13]:= {}; img[12]:= {5}; img[11]:= {}; img[10]:= {5}; img[9]:= {}; img[8]:= {5, 7, 9, 11, 13, 15}; img[7]:= {}; img[6]:= {5}; img[5]:= {}; img[4]:= {5}; img[3]:= {}; img[2]:= {5}; img[1]:= {}; ÿÿÿÿ€8ÀÔ5Ñþÿÿ€8ÀÔ#Syntax10.Scn.Fnt   img[16]:= {5}; img[15]:= {}; img[14]:= {5}; img[13]:= {}; img[12]:= {5}; img[11]:= {}; img[10]:= {5}; img[9]:= {}; img[8]:= {5, 7, 9,11, 13, 15}; img[7]:= {}; img[6]:= {}; img[5]:= {}; img[4]:= {}; img[3]:= {}; img[2]:= {}; img[1]:= {};ÿÿÿÿ€8ÀÔ5Äþÿÿ€8ÀÔ#Syntax10.Scn.Fnt img[15]:= {5}; img[14]:= {}; img[13]:= {5}; img[12]:= {1..9}; img[11]:= {1, 9}; img[10]:= {1, 9}; img[9]:= {1, 9}; img[8]:= {1, 9, 11, 13, 15}; img[7]:= {1, 9}; img[6]:= {1, 9}; img[5]:= {1, 9}; img[4]:= {1..9}; img[3]:= {}; img[2]:= {5}; img[1]:= {}; ÿÿÿÿ€8ÀÔ5Åþÿÿ€8ÀÔ#Syntax10.Scn.Fnt img[15]:= {5}; img[14]:= {}; img[13]:= {5}; img[12]:= {1..9}; img[11]:= {1, 9}; img[10]:= {1, 9}; img[9]:= {1, 9}; img[8]:= {1, 9, 11, 13, 15}; img[7]:= {1, 9}; img[6]:= {1, 9}; img[5]:= {1, 9}; img[4]:= {1..9}; img[3]:= {}; img[2]:= {}; img[1]:= {};ÿÿÿÿ€8ÀÔ6†ÿÿÿ€8ÀÔ#Syntax10.Scn.FntXX icon[5]:= {2}; icon[4]:= {2}; icon[3]:= {0..4}; icon[2]:= {2}; icon[1]:= {2}; ÿÿÿÿ€8ÀÔ4Šÿÿÿ€8ÀÔ#Syntax10.Scn.FntTT icon[5]:= {}; icon[4]:= {}; icon[3]:= {0..4}; icon[2]:= {}; icon[1]:= {}; ÿÿÿÿ€8ÀÔAe VAR img: ARRAY 17 OF SET; icon: ARRAY 6 OF SET; BEGIN (* plain *) treeIcons[0]:= Display.NewPattern(img, 16, 16); (* branch *) treeIcons[1]:= Display.NewPattern(img, 16, 16); (* aNode *) treeIcons[2]:= Display.NewPattern(img, 16, 16); (* lastNode *) treeIcons[3]:= Display.NewPattern(img, 16, 16); (* aFolder *) treeIcons[4]:= Display.NewPattern(img, 16, 16); (* lastFolder *) treeIcons[5]:= Display.NewPattern(img, 16, 16); (* plus *) foldDescr[0]:= Display.NewPattern(icon, 5, 5); (* minus *) foldDescr[1]:= Display.NewPattern(icon, 5, 5); END InitIcons;ÿÿÿÿ€8ÀÔ›¨MODULE TreeFrames; (* EK 98 *) IMPORT Display, Oberon, MenuViewers, Viewers, Texts, TextFrames, Trees, Fonts, Files, Input, FoldElems, GUtils, HandlerElems; CONST (** update message IDs **) replace* = Texts.replace; insert* = Texts.insert; delete* = Texts.delete; (** units **) Unit* = TextFrames.Unit; (** tree elems **) invisible= -1; plain= 0; branch= 1; aNode= 2; lastNode= 3; aFolder= 4; lastFolder= 5; plus= 0; minus= 1; W-= 16; H-= 16; (* width, height of one pattern *) hCol*= 13; (* color of hierarchy-tree *) (* mouse keys *) leftKey= 2; middleKey= 1; rightKey= 0; CR= 0AX; LF= 0DX; TYPE EditField = POINTER TO EditFieldDesc; EditFieldDesc= RECORD beg: LONGINT; curPos: SHORTINT; txtLen: SHORTINT; node: Trees.TreeNode; noNeutralize: BOOLEAN; (* ignore Oberon.ControlMsg with id = Oberon.neutralize *) END; Elem= POINTER TO ElemDesc; ElemDesc= RECORD (Texts.ElemDesc) id: INTEGER; END; NodeElem*= POINTER TO NodeElemDesc; NodeElemDesc*= RECORD (ElemDesc) node-: Trees.TreeNode; END; FolderElem*= POINTER TO FolderElemDesc; FolderElemDesc*= RECORD (NodeElemDesc) exp-: BOOLEAN; END; Frame* = POINTER TO FrameDesc; FrameDesc* = RECORD (TextFrames.FrameDesc) tree-: Trees.Tree; editable*: BOOLEAN; showEmptyTr*: BOOLEAN; (* shows empty trees as NodeElem *) drawBorder*: BOOLEAN; (* draws a border around editable nodes, while editing *) txtF: EditField; neHandler*: Texts.Handler; (* node element handler *) maxH*: SHORTINT; (* max height of one line *) END ; UpdateMsg* = RECORD (Display.FrameMsg) root*: Trees.Tree; id*: INTEGER; new*, old*: Trees.TreeNode; END ; SelectMsg* = RECORD (Display.FrameMsg) root*: Trees.Tree; node*: Trees.TreeNode; time*: LONGINT END ; UpdateProc= PROCEDURE (f: Frame; ne: NodeElem; VAR pos: LONGINT; n: Trees.TreeNode); VAR treeIcons: ARRAY 6 OF Display.Pattern; foldDescr: ARRAY 2 OF Display.Pattern; w: Texts.Writer; SuperHandle: Display.Handler; PROCEDURE NoTreeNotify (t: Trees.TreeNode; op: INTEGER); PROCEDURE NoTxtNotify (t: Texts.Text; op: INTEGER; beg, end: LONGINT); PROCEDURE NotifyDisplay* (root: Trees.Tree; new, old: Trees.TreeNode; op: INTEGER); (* View/Controll *) PROCEDURE Switch*(txt: Texts.Text; e: FolderElem); PROCEDURE Twin*(txt: Texts.Text; e: FolderElem): FoldElems.Elem; PROCEDURE ExpandAll*(t: Trees.Tree; f: Frame); PROCEDURE CollapseAll*(t: Trees.Tree; f: Frame); PROCEDURE ElemHandle (e: Texts.Elem; VAR msg: Texts.ElemMsg); PROCEDURE NodeElemHandle*(e: Texts.Elem; VAR msg: Texts.ElemMsg); PROCEDURE InitTreeElem(pl: BOOLEAN; e: Elem); PROCEDURE InitNodeElem(last: BOOLEAN; t: Trees.TreeNode; e: NodeElem); PROCEDURE InitFolderElem(last: BOOLEAN; t: Trees.Tree; exp: BOOLEAN; e: FolderElem); PROCEDURE DrawBranch(node: Trees.TreeNode); PROCEDURE PrintNode(VAR w: Texts.Writer; tn: Trees.TreeNode; e: NodeElem; empty: BOOLEAN); PROCEDURE PrintTree(fr: Frame; tree: Trees.Tree; (* no of lines per node *)); PROCEDURE CopyTreeToText*(fr: Frame); PROCEDURE AllocFoldElem*; PROCEDURE AllocFolderElem*; PROCEDURE AllocNodeElem*; PROCEDURE AllocTreeElem*; PROCEDURE DeleteNodeDesc(txt: Texts.Text; pos: LONGINT); (* in this version not implemented; maybe in a later version PROCEDURE InsertNode(f: Frame; ne: NodeElem; VAR pos: LONGINT; n: Trees.TreeNode); PROCEDURE DeleteNode(f: Frame; ne: NodeElem; VAR pos: LONGINT; n: Trees.TreeNode); PROCEDURE ReplaceNode(f: Frame; ne: NodeElem; VAR pos: LONGINT; n: Trees.TreeNode); *) PROCEDURE ChangeNode(f: Frame; ne: NodeElem; VAR pos: LONGINT; n: Trees.TreeNode); PROCEDURE UpdateNodeElem(f: Frame; msg: UpdateMsg; upd: UpdateProc); PROCEDURE GetNodeElem(f: Frame; y: INTEGER): NodeElem; PROCEDURE DrawBorder(f: Frame; id: INTEGER); PROCEDURE Defocus(f: Frame); PROCEDURE EditLine*(f: Frame; y: INTEGER); PROCEDURE KeyboardHandler(f: Frame; msg: Oberon.InputMsg); PROCEDURE InvertRect (F: Frame; x, y, w, h: INTEGER);(*clips to right and bottom frame margin*) PROCEDURE Copy (SF, DF: Frame); PROCEDURE Handle* (f: Display.Frame; VAR msg: Display.FrameMsg); PROCEDURE Open* (F: Frame; T: Trees.Tree); PROCEDURE NewTree* (t: Trees.Tree): Frame; PROCEDURE NewTreewHandler*(t: Trees.Tree; h: Texts.Handler): Frame; PROCEDURE Tree*(): Trees.Tree; PROCEDURE NewMenu* (name, commands: ARRAY OF CHAR): TextFrames.Frame; PROCEDURE InitIcons; BEGIN InitIcons; HandlerElems.SetHandler("TreeFrames.Handler", Handle, SuperHandle); END TreeFrames. an application: see HierEdit.Open HierEdit.Mod