CDX:
CEDAR
DEFINITIONS
IMPORTS CDInline =
BEGIN
--Public interface between chipndale and outside clients.
--Maps chipndales complex and mutable (but fast on displaying)
--positioning mechanism to an immutable "client" cordinate system.
--The Origin is a hypothtical point of an object; the client's coordinate
--system origin.
ClientPosition: TYPE = CD.Position;
ClientRect: TYPE = CD.Rect;
ClientOrigin:
PROC [ob:
CD.ObPtr]
RETURNS [pos:
CD.DesignPosition];
--Returns the position of the client's object origin in objects internal cd coords
ClientRectI:
PROC [ob:
CD.ObPtr]
RETURNS [ClientRect] =
--Returns the inner - rect in client's relative coords
INLINE {RETURN [CDInline.MoveRect[ob.p.insideRect[ob], CDInline.NegOffset[ClientOrigin[ob]]]]};
ClientRectO:
PROC [ob:
CD.ObPtr]
RETURNS [ClientRect] =
--Returns the real outside (repaint..) rect in client's relative coords
INLINE {RETURN [CDInline.MoveRect[CDInline.RectAt[[0, 0], ob.size], CDInline.NegOffset[ClientOrigin[ob]]]]};
--Transfer between chipndale and client coordinates, both relative to the object
CDToClientPos:
PROC [ob:
CD.ObPtr, pos:
CD.DesignPosition←[0, 0]]
RETURNS [cPos: ClientPosition] =
INLINE {
RETURN [CDInline.SubPoints[pos, ClientOrigin[ob]]]};
ClientToCDPos:
PROC [ob:
CD.ObPtr, cPos: ClientPosition←[0, 0]]
RETURNS [pos:
CD.DesignPosition] =
INLINE {RETURN [CDInline.AddPoints[cPos, ClientOrigin[ob]]]};
CDToClientRect:
PROC [ob:
CD.ObPtr, rect:
CD.DesignRect]
RETURNS [cRect: ClientRect] =
INLINE BEGIN
co: CD.DesignPosition = ClientOrigin[ob];
RETURN [ClientRect[x1: rect.x1-co.x, y1: rect.y1-co.y, x2: rect.x2-co.x, y2: rect.y2-co.y]]
END;
ClientToCDRect:
PROC [ob:
CD.ObPtr, cRect: ClientRect]
RETURNS [rect:
CD.DesignRect] =
INLINE BEGIN
co: CD.DesignPosition = ClientOrigin[ob];
RETURN [CD.DesignRect[x1: cRect.x1+co.x, y1: cRect.y1+co.y, x2: cRect.x2+co.x, y2: cRect.y2+co.y]]
END;
--Transfer between client object relative coordinates and chipndale global coordinates
MapClientPos: PROC [cPos: ClientPosition←[0, 0], app: CD.ApplicationPtr] RETURNS [globPos: CD.DesignPosition];
DeMapClientPos: PROC [globPos: CD.DesignPosition, app: CD.ApplicationPtr] RETURNS [cPos: ClientPosition];
MapClientRect: PROC [cRect: ClientRect, app: CD.ApplicationPtr] RETURNS [globRect: CD.DesignRect];
DeMapClientRect:
PROC [globRect:
CD.DesignRect, app:
CD.ApplicationPtr]
RETURNS [cRect: ClientRect];
PositionFromPairO:
PROC [ob:
CD.ObPtr,
cPos: ClientPosition←[0,0],
correspondingGlobPos: CD.DesignPosition←[0,0],
orientation: CD.Orientation𡤀
] RETURNS [appPos: CD.DesignPosition];
--Computes a position useable for an application, such that the
--client-origin relative point cPos is at the global position correspondingGlobPos
PositionFromPairI:
PROC [ob:
CD.ObPtr,
cPos: ClientPosition←[0,0],
correspondingGlobPos: CD.DesignPosition←[0,0],
orientation: CD.Orientation𡤀
] RETURNS [iPos: CD.DesignPosition];
--Computes the position of the innerrect, such that the client-origin
--relative point cPos is at the global position correspondingGlobPos
--Relative placement
CoordSystem: TYPE = {outerCoordinates, innerCoordinates, clientCoordinates};
IncludeRelative:
PROC [design:
CD.Design←
NIL, cell:
CD.ObPtr←
NIL, ob:
CD.ObPtr,
cellPosition: CD.Position←[0, 0],
obPosition: CD.Position←[0, 0],
orientation: CD.Orientation𡤀,
coordSystem: CoordSystem𡤌lientCoordinates,
skipRepositioning: BOOL←FALSE] RETURNS [CD.ApplicationPtr];
--design (NIL: allowed, if cell really is not yet part of a design)
--cell (NIL: include into design; assumes the designs origin at [0, 0])
-- (design&cell NIL: simply create an application)
--ob: object to include in cell
--cellPosition, obPosition: include is done such that these points will match
--orientation: of ob inside cell
--coordSystem: uses either clientCoordinates or cdCoordinates for both,
-- the reference point of the cell and the reference point of the object
--skipRepositioning: delays repositioning of the cell
-- caution: makes temporary a wrong coordinate system! cell is
-- not legal until CDDirectory.RepositionAnObject[cell] is called to clean up.
-- skipRepositioning has no effect if cell is NIL
--caution: procedure does NOT redraw the viewers; (use CDOps.DelayedRedraw...)
--notification business
NotificationRec:
TYPE =
RECORD[me:
CD.ObPtr, old, new:
CD.DesignPosition];
--On coordinate system change: old was valid in old coordinate system, new in
--new coordinate system.
originMoveEvent:
READONLY
REF;
--For registration of an CDEvent called on changes of the client origin
--If an origin change is combined with another change, e.g. involving CDEvents
--afterChange, or afterPop, make no assumption on the order of the notifications;
--however, this notification will not be ommited.
--The EventProc's x parameter will be of type NotificationRec.
--changing the origin
SetClientOrigin:
PROC [design:
CD.Design, ob:
CD.ObPtr, pos:
CD.DesignPosition];
--Calls objects SetOriginProc.
--Sets the position of the client's object origin measured in objects
--internal coords.
--This procedure has horrible side effects.
--It should be called only by the implementor of repositioning, and,
--rarely, restricted to certain object classes, interactively driven.
--Object class implementors business; calling these procedures for other purposes
-- (except if explicitely allowed by the comment of a procedure) will typically
-- produce chaos.
GetOriginProc: TYPE = PROC[ob: CD.ObPtr] RETURNS [CD.DesignPosition];
SetOriginProc: TYPE = PROC[design: CD.Design, ob: CD.ObPtr, new: CD.DesignPosition];
CallDefaultGetOrigin: PROC[ob: CD.ObPtr] RETURNS [CD.DesignPosition];
CallDefaultSetOrigin:
PROC[design:
CD.Design, ob:
CD.ObPtr, new:
CD.DesignPosition];
--BUT does NOT do the notification
CallNotification:
PROC [design:
CD.Design, me:
CD.ObPtr, old, new:
CD.DesignPosition];
--causes an CDEvents notification event
RegisterOriginProcs:
PROC [class:
REF
CD.ObjectProcs,
set: SetOriginProc, --don't use CallDefaultSetOrigin; it would not notify !
get: GetOriginProc
];
END.