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, August 16, 1984 4:45:06 pm PDT
DIRECTORY
DB,
Icons USING [IconFlavor],
IO,
Menus USING[MenuProc, MenuEntry],
MBQueue USING [Queue],
NutButtons USING [ButtonFontInfo, Queue],
Buttons,
Rope,
ViewerClasses;
NutViewer: CEDAR DEFINITIONS =
BEGIN OPEN DB;
Viewer: TYPE = ViewerClasses.Viewer;
ROPE: TYPE = Rope.ROPE;
Queue: TYPE = NutButtons.Queue;
EnumProc: TYPE = PROC[enum: REF ANY] RETURNS [label: Rope.ROPE];
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[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.
IsDefaultViewer: PROC[v: Viewer] RETURNS[BOOL];
This will return TRUE iff the viewer was created by CreateDefaultViewer (which are also used bu the operations SpawnViewer, ReplaceViewer and OneViewer).
SpawnViewer: PROC[eName, domain: ROPE, seg: Segment, parent: Viewer ← NIL] RETURNS[newV: Viewer];
Create a new Viewer for this entity and domain, replacing the last viewer spawned from the parent (if any) and sets the spawned property of the parent. This Viewer is a container labelled appropriately.
ReplaceViewer: PROC[eName, domain: ROPE, seg: Segment, parent: Viewer ← NIL] RETURNS[newV: Viewer];
Create a new Viewer for this entity and domain and replace the parent with it (if the parent does not have the old version bit set)
OneViewer: PROC[eName, domain: ROPE, seg: Segment, parent: Viewer ← NIL] RETURNS[newV: Viewer];
Create a new Viewer for this entity and domain, either using the spawned viewer (if possible) or any other default viewer currently displaying or editing the given entity
CreateDefaultViewer: PROC[eName, domain: ROPE, segment: DB.Segment, replace: Viewer ← NIL] RETURNS [newV: Viewer];
The procedure to perform all of the above options -- this one replaces the given viewer (if it is not NIL) with an empty Container (properly labelled and set to be used by the defaults)
*************************************
-- 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
*******************************************************************
-- 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: NutButtons.ButtonFontInfo ← NIL, newLine: BOOLFALSE, visible: BOOLTRUE]
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
DefaultFreezeProc: Menus.MenuProc;
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. This also sets a typescript property of the parent viewer (sib.parent) that can be later retreived by the procedure below
GetTypescript: PROC[v: Viewer] RETURNS [out: IO.STREAM];
Return the typescript property set by MakeTypescript
MakeRuler: PROC[sib: Viewer, h: INTEGER← 1] RETURNS [r: Viewer];
Put a h-bit wide line after sib. We assume sib.parent#NIL.
MakeBigTextBox: 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]]};
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.