File: NutViewer.mesa
Contents: Handy Squirrel procedures for building database application Viewers.
Created by: Rick Cattell on 11-Dec-81 12:29:29
Last edited by:
Cattell, July 5, 1983 4:48 pm
Willie-Sue on: January 21, 1983 8:48 am
Donahue, July 29, 1983 9:41 am
Widom, June 15, 1984 1:27:02 pm PDT
Butler, June 26, 1984 4:36:51 pm PDT
DIRECTORY
DB,
Icons USING [IconFlavor],
IO,
MBQueue USING [Queue],
Buttons, Menus, Rope, ViewerClasses, VFonts;
NutViewer: CEDAR DEFINITIONS
IMPORTS VFonts =
BEGIN OPEN DB;
Viewer: TYPE = ViewerClasses.Viewer;
ROPE: TYPE = Rope.ROPE;
Queue: TYPE = MBQueue.Queue;
stopped: BOOLEAN;
squirrel: ViewerClasses.Viewer; -- the Squirrel viewer, NIL if not open
squirrelOut: IO.STREAM; -- the Squirrel output stream (may be IO.NoWhereStream)
ToolViewer: ROPE; -- the name of the tool viewer domain used in Find and Convert
TextViewer: ROPE; -- the name of the text viewer domain used in Find and Convert
EnumProc: TYPE =
PROC[enum: REF ANY] RETURNS [label: Rope.ROPE, thing: REF ANY];
Returns next or previous element of the enumeration
CountProc: TYPE =
PROC[v: Viewer, enum: REF ANY] RETURNS [INT];
Estimate size of enumeration. Used only for feedback so may be approximate.
ThumbProc: TYPE =
PROC[v: Viewer, enum: REF ANY, where: NAT] RETURNS [newEnum: REF ANY];
Use to set enumeration to particular position quickly; may return new enum.
The where parameter is a percentage between 0 and 100.
*******************************************************************
--- NutViewerImpl --
The following procedures and functions are used by the default display, edit, and query
procedures for domains, relations, and the general default case
*******************************************************************
Initialize: PROC[parent: Viewer] RETURNS [nV: Viewer];
Initializes a viewer so that MakeButton, MakeLabel, MakeTextViewer, etc., may be used.
The argument nV returned is passed along through each call to keep track of sibling pos'n,
e.g.: nV← MakeLabel["Foo", nV].
MakeLabel: PROC[name: ROPE, sib: Viewer, newLine: BOOLFALSE] RETURNS [nV: Viewer];
The sib is a viewer to the left or above the label to be made, according to newLine.
SpawnViewer: PROC[eName: ROPE ← NIL, e: Entity ← NIL, d: Domain ← NIL, seg: Segment ← NIL, parent: Viewer ← NIL]
RETURNS[newV: Viewer];
ReplaceViewer: PROC[eName: ROPE ← NIL, e: Entity ← NIL, d: Domain ← NIL, seg: Segment ← NIL, parent: Viewer ← NIL]
RETURNS[newV: Viewer];
OneViewer: PROC[eName: ROPENIL, e: Entity ← NIL, d: Domain ← NIL, seg: Segment ← NIL, parent: Viewer ← NIL]
RETURNS[newV: Viewer];
*************************************
-- NutViewerImpl --
Message procedures for interacting with user
*************************************
Message: PROC[v: ViewerClasses.Viewer, msg1, msg2, msg3, msg4: Rope.ROPENIL];
If the top level viewer in which v is nested has a $Typescript property, then
prints the concatenated values msg1 through msg4 on the stream that is the value
of that property. Otherwise, if the Squirrel window is on the screen, prints the
messages in the Squirrel window. Otherwise, sprint the messages in the Message area.
Error: PROC[v: ViewerClasses.Viewer, msg1, msg2, msg3, msg4: Rope.ROPENIL];
Same as Message proc above, but blinks the screen first.
MessageRope: PROC[v: ViewerClasses.Viewer, msg: Rope.ROPENIL];
Prints the given msg as with Message proc above, but without CR
GetIcon: PROC[e: Entity, seg: Segment ← NIL] RETURNS[icon: Icons.IconFlavor];
GetNutInfo: PROC[v: Viewer] RETURNS[segment: Segment, domain: Domain, entity: ROPE];
Returns segment, domain, and entity name (if any) using the $Segment, $Domain, and
$Entity properties set up by the [default] create proc.
*******************************************************************
-- NutViewerMiscImpl.mesa --
Handy procedures for dealing with viewers.
These procedures can be used by applications to created menus, buttons, labels, and text
viewers which are automatically placed at the next x/y position in the parent viewer.
In the case of menus and buttons, they are automatically given a top-level catch phrase
for database errors and are synchronized with an MBQueue specified as argument.
A default MBQueue may be used, or the synchronization and catch phrases may be
omitted by passing a NIL MBQueue. Some examples of the use of these procedures:
nV: Viewer← Initialize[parent];
nV← MakeButton[DBQueue[], "Name: ", SelectProc, nV]; (Makes button on top line)
nV← MakeTextViewer[sib: nV, fullLine: FALSE]; (Make text label on same line)
[]← MakeTypeScript[nV]; (Make a typescript at the end of the window).
********************************************************************
MakeButton: PROC[q: Queue, name: ROPE, proc: Buttons.ButtonProc, sib: Viewer, data: REF ANYNIL, border: BOOLFALSE, width: INTEGER← 0, guarded: BOOLFALSE, font: VFonts.Font ← VFonts.defaultFont, newLine: BOOLFALSE] RETURNS [nV: Viewer];
Creates a new button, to the right or below sib, according to newLine.
MakeMenuEntry: PROC[q: Queue, name: ROPE, proc: Menus.MenuProc, clientData: REF ANYNIL, documentation: REF ANYNIL, fork: BOOLTRUE, guarded: BOOLFALSE] RETURNS[Menus.MenuEntry];
Creates a menu entry, suitable to use as follows:
Menus.AppendMenuEntry[myMenu, MakeMenuEntry[...]].
Main purpose of this procedure is to allow menu items to be queued.
DBQueue: PROC RETURNS[Queue];
Returns Squirrel's default Queue. E.g., can be used as follows:
nV ← MakeButton[DBQueue[], "Foo", FooProc, nV].
NextRightTextViewer: PROC[sib: Viewer, w: INTEGER] RETURNS [nV: Viewer];
Backwards compatible: creates a text viewer, next right on the same line as v
CheckAborted: PROC[sib: Viewer];
DefaultFreezeProc: Menus.MenuProc;
A standard proc for freezing a Nut (make it not reuseable).
***************** Mapping between entities and viewers *******************
MakeTextViewer: PROC[sib: Viewer, w: INTEGER← 0, fullLine: BOOLFALSE] RETURNS [nV: Viewer];
Creates a text viewer, next right on the same line as v, or full width of next line
if fullLine=TRUE
MakeTypescript: PROC[sib: Viewer] RETURNS [ts: Viewer];
The sib is sibling to create TS after, this must be last child of non-NIL sib.parent.
MakeRuler: PROC[sib: Viewer, h: INTEGER← 1] RETURNS [r: Viewer];
Put a h-bit wide line after sib. We assume sib.parent#NIL.
MakeBigTextBox: PUBLIC PROC[sib: Viewer, contents: ROPE] RETURNS [nV: Viewer];
Makes editable text viewer taking rest of sib.parent's viewer, suitable for msg body or
whatever. The sib is a sibling to create text box after, this must be last child of sib.parent.
Again, we assume sib.parent#NIL.
NextTextViewer: PROC[sib: Viewer] RETURNS [nV: Viewer] = INLINE {
Backwards compatible: creates text viewer on line following sib, full width of sib.parent
RETURN[MakeTextViewer[sib, , TRUE]]};
*****************************************************
-- NutViewerWindowImpl --
-- window stuff
*****************************************************
CreateMBWindow: PROC[
next, prev: EnumProc, -- to go forward and backward in the enumeration
thumb: ThumbProc, -- to create an enumeration set to a particular position
count: CountProc, -- to give total size of enumeration
buttonProc: Buttons.ButtonProc, -- called with the thing associated with button
info: ViewerClasses.ViewerRec← [], -- allows client to fill in ViewerRec fields
initialScroll: INT← 0, -- what percentage of scroll to have for initial display
q: MBQueue.Queue← NIL] -- MBQueue under which to synchronize (doesn't yet work)
RETURNS [viewer: Viewer];
Client's buttonProc must be prepared to be called with an empty button (clientData and label NIL), as there will always be one screenheight of buttons even if they're not all occupied. It should do nothing in this case. Client's next proc should return [NIL, NIL] when there are no more items to enumerate. It may be called again after that, in which case it should continue to return [NIL, NIL]. Similarly for prev proc at beginning of list. Client's count procedure is used only for providing feedback in scroll bar, so it need not be exactly right. MBWindows will tolerate some inconsistency in the client's procedures, e.g. enumerating the same item twice when change from next to prev proc.
Notice we do not need an initial REF ANY for the enumeration; it is created by calling the thumb procedure with where=initialScroll and enum=NIL. Note also that we allow the thumb procedure to create a new enumeration, while the next and prev procedures are expected to make any modification to the enum they are passed in place (they may modify it, because MBWindows has a REF to it).
Note: if the MBWindow is nested inside another viewer, then the parent field should be set by passing a parent in the info field, and the client should call Containers.ChildYBound so that the MBWindow's size is set automatically with changes in the parent. See example below.
END.