DIRECTORY
Commander, FileNames, FS, GGCaret, GGContainer, GGError, GGInterfaceTypes, GGMenus, GGModelTypes, GGObjects, GGRefresh, GGUserInput, GGVector, GGViewerOps, GGWindow, Icons, Imager, ImagerBackdoor, IO, Menus, Rope, TiogaButtons, TIPUser, ViewerClasses, ViewerOps;

GGWindowImpl: CEDAR PROGRAM
IMPORTS Commander, FileNames, FS, GGCaret, Icons, Imager, ImagerBackdoor, GGContainer, GGError, GGMenus, GGObjects, GGRefresh, GGUserInput, GGVector, GGViewerOps, Menus, Rope, TIPUser, ViewerOps
EXPORTS GGWindow
SHARES ViewerClasses =

BEGIN

Camera: TYPE = REF CameraObj;
CameraObj: TYPE = GGModelTypes.CameraObj;
Caret: TYPE = REF CaretObj;
CaretObj: TYPE = GGInterfaceTypes.CaretObj;
Cluster: TYPE = GGModelTypes.Cluster;
ImagerProc: TYPE = GGInterfaceTypes.ImagerProc;
MouseButton: TYPE = Menus.MouseButton;
Outline: TYPE = GGModelTypes.Outline;
PaintQueue: TYPE = REF PaintQueueObj;
PaintQueueObj: TYPE = GGInterfaceTypes.PaintQueueObj;
Point: TYPE = GGModelTypes.Point;
Scene: TYPE =  REF SceneObj;
SceneObj: TYPE = GGModelTypes.SceneObj;
Segment: TYPE = GGModelTypes.Segment;
Sequence: TYPE = GGModelTypes.Sequence;
Traj: TYPE = GGModelTypes.Traj;
Viewer: TYPE = ViewerClasses.Viewer;

GargoyleData: TYPE = REF GargoyleDataObj;
GargoyleDataObj: TYPE = GGInterfaceTypes.GargoyleDataObj;

entryHeight: CARDINAL = 15; -- height of a line of items
entryVSpace: CARDINAL = 2; -- vertical leading between lines
entryHSpace: CARDINAL = 2; -- horizontal space between items on a line
column1: CARDINAL = 200; -- horizontal space between margin and column 1;
column2: CARDINAL = 250; -- horizontal space between margin and column 2.
column3: CARDINAL = 500; -- horizontal space between margin and column 3;
nameSize: CARDINAL = 140;
smallNumberSize: CARDINAL = 45;
numberSize: CARDINAL = 80;
bigNumberSize: CARDINAL = 160;
pointSize: CARDINAL = 160;

ActionAreaPaint: PROC [self: Viewer, context: Imager.Context, whatChanged: REF ANY, clear: BOOL] RETURNS [quit: BOOL _ FALSE] = TRUSTED {
gargoyleData: GargoyleData;
IF whatChanged = NIL THEN { --we are being called by Window Manager
gargoyleData _ NARROW[self.data];
PlaceOrigin[self];
Painter[$PaintEntireScene, gargoyleData];
}
ELSE {
gargoyleData _ NARROW[whatChanged];
GGRefresh.ActionAreaPaint[context, gargoyleData.refresh.paintAction, gargoyleData];
};
};
 
Painter: PUBLIC PROC [paintAction: ATOM, gargoyleData: GargoyleData] = {
gargoyleData.refresh.paintAction _ paintAction;
ViewerOps.PaintViewer[
viewer: gargoyleData.actionArea,
hint: client,
whatChanged: gargoyleData,
clearClient: FALSE];
}; -- end of Painter

PlaceOrigin: PROC [viewer: Viewer] = TRUSTED {
originX, originY: INTEGER;
rect: Imager.Rectangle;
gargoyleData: GargoyleData _ NARROW[viewer.data];
originX _ viewer.cw; -- convert window width to real
originY _ viewer.ch; -- convert window height to real
originX _ originX/2; -- find the midpoint in window coords
originY _ originY/2;
gargoyleData.camera.cameraScreen _ [originX, originY];

gargoyleData.refresh.backgroundBitmap _ ImagerBackdoor.NewBitmap[viewer.cw, viewer.ch];
gargoyleData.refresh.backgroundContext _ ImagerBackdoor.BitmapContext[gargoyleData.refresh.backgroundBitmap];

gargoyleData.refresh.chunkingBitmap _ ImagerBackdoor.NewBitmap[viewer.cw, viewer.ch];
gargoyleData.refresh.chunkingContext _ ImagerBackdoor.BitmapContext[gargoyleData.refresh.chunkingBitmap];
rect _ ImagerBackdoor.GetBounds[gargoyleData.refresh.backgroundContext];
Imager.SetColor[gargoyleData.refresh.backgroundContext, Imager.white];
Imager.MaskRectangle[gargoyleData.refresh.backgroundContext, rect];
};



CameraToScreen: PUBLIC PROC [pointCamera: Point, camera: Camera] RETURNS [pointScreen: Point] = {
pointScreen _ GGVector.Add[pointCamera, camera.cameraScreen];
};

ScreenToCamera: PUBLIC PROC [pointScreen: Point, camera: Camera] RETURNS [pointCamera: Point] = {
pointCamera _ GGVector.Sub[pointScreen, camera.cameraScreen];
};

ScreenToWorld: PUBLIC PROC [pointScreen: Point, camera: Camera] RETURNS [pointWorld: Point] = {
pointCamera: Point;
pointCamera _ GGVector.Sub[pointScreen, camera.cameraScreen];
pointWorld _ GGVector.Add[pointCamera, camera.cameraWorld];
};

Init: PROC = {
actionAreaClass: ViewerClasses.ViewerClass;
 
actionAreaClass _ 
NEW[ViewerClasses.ViewerClassRec _ [
paint: ActionAreaPaint,
notify: GGUserInput.InputNotify,
tipTable: TIPUser.InstantiateNewTIPTable["Gargoyle.TIP"]
]];
 
ViewerOps.RegisterViewerClass[$ActionArea, actionAreaClass];
Commander.Register[
key: "Gargoyle",
proc: NewWindow,
doc: "Create a Gargoyle Graphics Window",
clientData: NIL
];
};


NewWindow: Commander.CommandProc = {
scene: Scene _ GGObjects.CreateScene[];
[] _ CreateWindow[scene, TRUE, TRUE, FileNames.CurrentWorkingDirectory[]];
};


CreateWindow: PUBLIC PROC [scene: Scene, iconic: BOOL, paint: BOOL, workingDirectory: Rope.ROPE] RETURNS [gargoyleData: GargoyleData] = {

windowMenu: Menus.Menu _ Menus.CreateMenu[3];
iconFileName: Rope.ROPE;

gargoyleData _ NEW[GargoyleDataObj];
gargoyleData.originalWorkingDirectory _ FileNames.CurrentWorkingDirectory[];
gargoyleData.scene _ scene;
gargoyleData.camera _ NEW[CameraObj _ [[0.0, 0.0], 1.0, [0.0, 0.0]]];
gargoyleData.caret _ NEW[CaretObj];
gargoyleData.anchor _ NEW[CaretObj];
gargoyleData.currentAction _ $None;

iconFileName _ Rope.Concat[gargoyleData.originalWorkingDirectory, "Gargoyle.icons"];
gargoyleData.outer _ GGContainer.Create[
info: [
name: "Gargoyle",
menu: windowMenu,
data: gargoyleData,
iconic: TRUE,
column: left,
scrollable: FALSE,
icon: Icons.NewIconFromFile[iconFileName, 0]
],
paint: FALSE];

GGMenus.BuildControlPanel[gargoyleData, windowMenu];


BuildActionArea[gargoyleData];

ViewerOps.OpenIcon[icon: gargoyleData.outer, closeOthers: FALSE, bottom: FALSE, paint: TRUE];
};


BuildActionArea: PRIVATE PROC [gargoyleData: GargoyleData] = {
gargoyleData.actionArea _ ViewerOps.CreateViewer[
flavor: $ActionArea,
info: [
parent: gargoyleData.outer,
wx: 0, wy: gargoyleData.height,
ww: gargoyleData.outer.ww,
wh: gargoyleData.outer.wh, -- only initial values for ww and wh.  They are constrained below
data: gargoyleData,
scrollable: FALSE
]
];
GGContainer.ChildXBound[gargoyleData.outer, gargoyleData.actionArea];
GGContainer.ChildYBound[gargoyleData.outer, gargoyleData.actionArea];

gargoyleData.height _ gargoyleData.height + gargoyleData.actionArea.wh;

}; -- end of BuildActionArea

ReloadTipTable: PUBLIC PROC [gargoyleData: GargoyleData] = {
newTable: TIPUser.TIPTable;
actionArea: ViewerClasses.Viewer;
bad: BOOL _ FALSE;
tableName, msg: Rope.ROPE;
GGError.AppendHerald["Reloading tip table...", TRUE];
tableName _ Rope.Concat[gargoyleData.originalWorkingDirectory, "Gargoyle.TIP"];
newTable _ TIPUser.InstantiateNewTIPTable[tableName
! FS.Error => {
bad _ TRUE; 
msg _ Rope.Concat["Cannot read TIP table file: ", tableName];
CONTINUE};
TIPUser.InvalidTable => {
bad _ TRUE;
msg _ Rope.Concat["Error(s) saved on TIP.Errors for: ", tableName];
CONTINUE}];
IF bad THEN {GGError.Append[msg, oneLiner]; RETURN};
GGError.AppendHerald["Done.", FALSE];
IF newTable = NIL THEN ERROR;
actionArea _ gargoyleData.actionArea;
actionArea.tipTable _ newTable;
};

NewCaretPos: PUBLIC PROC [gargoyleData: GargoyleData] = {
oldCaretPos, newCaretPos: Point;
success: BOOL;
distance: REAL;
[oldCaretPos, success] _ GGViewerOps.GetPoint[gargoyleData.distanceLine.oldCaret];
newCaretPos _ GGCaret.GetPoint[gargoyleData.caret];
IF NOT success THEN RETURN;
distance _ GGVector.Distance[oldCaretPos, newCaretPos];
GGViewerOps.SetReal[gargoyleData.distanceLine.distance, distance];
GGViewerOps.SetPoint[gargoyleData.distanceLine.newCaret, newCaretPos];
};

SaveCaretPos: PUBLIC PROC [gargoyleData: GargoyleData] = {
caretPos: Point;
caretPos _ GGCaret.GetPoint[gargoyleData.caret];
GGViewerOps.SetPoint[gargoyleData.distanceLine.oldCaret, caretPos];
};



Init[];


END.


����File: GGWindowImpl.mesa
Author: Eric Bier on June 5, 1985 11:34:50 pm PDT
Copyright c 1985 by Xerox Corporation.  All rights reserved.
Last edited by Bier on August 17, 1985 5:39:02 pm PDT
Contents: Code to create a Gargoyle window.  Calls GGContainer to make the container and adds menus at the top.  The graphics part of the Gargoyle window is a new viewer of class $ActionArea.  The paint proc for a $ActionArea is defined herein.
Stone, July 15, 1985 11:39:29 am PDT
ViewerClasses.PaintProc
whatChanged is a GargoyleData.  self is an ActionArea.
viewer is the ActionArea.  The camera for this view represents the translation from the center of the window in screen dots and a scaling factor.
 Find the center of the ActionArea in viewer coordinates.
Initialize the context to white.
Create the Container and the top menu which looks like this:
Clear, Reset, Get, Store, Save, Split, Erase
Construct the outer container.
Create an ActionArea which fills the bottom of the Gargoyle Container
Ê­��˜�Iheadšœ™Iprocšœ1™1Jšœ
Ïmœ1™<Lšœ5™5šœô™ôIcode™$—L˜�šÏk	˜	Lšœžœî˜†L˜�—šœžœž˜Lšžœžœ¢˜ÂLšžœ	˜Lšžœ˜—L˜�Lšž˜˜�Lšœžœžœ˜Lšœžœ˜)Lšœžœžœ
˜Lšœ
žœ˜+Lšœ	žœ˜%Lšœžœ˜/Lšœ
žœ˜&Lšœ	žœ˜%Lšœžœžœ˜%Lšœžœ"˜5Lšœžœ˜!Lšœžœžœ
˜Lšœ
žœ˜'Lšœ	žœ˜%Lšœ
žœ˜'Lšœžœ˜Lšœžœ˜$L˜�Lšœžœžœ˜)Lšœžœ$˜9L˜�Lšœ
žœÏc˜8Lšœ
žœŸ!˜<Lšœ
žœŸ+˜FLšœ	žœŸ0˜ILšœ	žœŸ0˜ILšœ	žœŸ0˜ILšœ
žœ˜Lšœžœ˜Lšœžœ˜Lšœžœ˜Lšœžœ˜L˜�—šÏnœžœ6žœžœ	žœžœžœžœžœ˜‰Lšœ™Lšœ6™6Lšœ˜šžœžœžœŸ'˜CLšœžœ˜!Lšœ˜Lšœ)˜)Lšœ˜—šžœ˜Lšœžœ˜#LšœS˜SLšœ˜—Lšœ˜—Lšœ˜š œžœžœžœ!˜HLšœ/˜/šœ˜Lšœ ˜ Lšœ
˜
Lšœ˜Lšœ
žœ˜—LšœŸ˜L˜�—š œžœžœ˜.Lšœ‘™‘Lšœ9™9Lšœžœ˜Jšœ˜Lšœžœ˜1LšœŸ ˜4LšœŸ!˜5LšœŸ&˜:Lšœ˜LšœÏuœ˜6L˜�LšœW˜WLšœm˜mL˜�LšœU˜Ušœi˜iJ™ —JšœH˜HJšœF˜FJšœC˜CLšœ˜L˜�—L˜�L˜�š œžœžœ¡œžœ¡œ˜aLšœ¡œ¡œ¡œ˜=L˜L˜�—š œžœžœ¡œžœ¡œ˜aLšœ¡œ¡œ¡œ˜=L˜L˜�—š 
œžœžœ¡œžœ¡œ˜_Lšœ¡œ˜Lšœ¡œ¡œ¡œ˜=Lšœ¡œ¡œ¡œ˜;L˜L˜�—š œžœ˜Lšœ+˜+Lšœ˜Lšœ˜šžœ!˜$Lšœ˜Lšœ ˜ Lšœ8˜8Lšœ˜—Lšœ˜Lšœ<˜<šœ˜Lšœ˜Lšœ˜Lšœ)˜)Lšœž˜L˜—Lšœ˜—L˜�L˜�šœ$˜$Lšœ'˜'Lšœžœžœ'˜JL˜L˜�—L˜�š œžœžœžœ	žœžœžœ!˜‰Lšœ<™<Lšœ,™,L˜�Lšœ-˜-Lšœžœ˜L˜�Lšœžœ˜$LšœL˜LLšœÏbœ˜Lšœžœ,˜ELšœžœ˜#Lšœžœ˜$Lšœ#˜#L˜�Lšœ™LšœT˜Tšœ(˜(šœ˜Lšœ˜Lšœ˜Lšœ˜Lšœžœ˜
Lšœ
˜
Lšœžœ˜Lšœ,˜,Lšœ˜—Lšœžœ˜L˜�—Lšœ4˜4L˜�L˜�Lšœ˜L˜�Lšœ:žœ
žœ	žœ˜]Lšœ˜L˜�L˜�—š œžœžœ!˜>LšœE™Ešœ1˜1Lšœ˜šœ˜Lšœ˜Lšœ˜Lšœ˜LšœŸA˜\Lšœ˜Lšœž˜Lšœ˜—Lšœ˜—LšœE˜ELšœE˜EL˜�LšœG˜GL˜�LšœŸ˜—L˜�š œžœžœ!˜<Lšœ˜L˜!Lšœžœžœ˜Lšœžœ˜Lšœ/žœ˜5LšœO˜Ošœ3˜3šœžœ˜Jšœžœ˜Jšœ=˜=Jšžœ˜
—šœ˜Jšœžœ˜JšœC˜CJšžœ˜——Jšžœžœ!žœ˜4Jšœžœ˜%Jšžœžœžœžœ˜Lšœ%˜%Lšœ˜L˜L˜�—š œžœžœ!˜9Lšœ ˜ Lšœ	žœ˜Lšœ
žœ˜LšœR˜RLšœ3˜3Lšžœžœ	žœžœ˜Lšœ7˜7LšœB˜BLšœF˜FL˜L˜�—š œžœžœ!˜:Lšœ˜Lšœ0˜0LšœC˜CL˜L˜�L˜�L˜�—šœ˜L˜�—L˜�Lšžœ˜J˜�J˜�—�…—������+%��