🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: mod.mac.sources
1 messages
1 total messages Started by macintosh Tue, 27 Jan 1987 15:25
BMgr - Blob Manager source (part 1 of 2)
#33
Author: macintosh
Date: Tue, 27 Jan 1987 15:25
1285 lines
32491 bytes
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	BMgr/BlobMgr.h
#	BMgr/BMgrCalcRegion.c
#	BMgr/BMgrClick.c
#	BMgr/BMgrDrag.c
#	BMgr/BMgrDraw.c
#	BMgr/BMgrFlags.c
#	BMgr/BMgrFreeze.c
#	BMgr/BMgrHideShow.c
mkdir BMgr
sed 's/^X//' << 'SHAR_EOF' > BMgr/BlobMgr.h
X/*	Blob Manager global types and constants	*/
X
X# ifndef	_BlobMgr_
X
X# define	_BlobMgr_
X
X# ifndef	_Quickdraw_
X#include <QuickDraw.h>	/* brings in MacTypes.h as well */
X# endif
X
X# ifndef	nil
X# define	nil		0L
X# endif
X
X
X/*	blob flag masks  */
X
Xenum
X{
X	bEnableMask = 1,
X	bFreezeMask = 2,
X	bStatModeMask = 4,
X	bDragModeMask = 8,
X	bDrawModeMask = 12,	/* two bits, derived: bStatModeMask + bDragModeMask */
X	bNeedGlobMask = 16,
X	bScaleMask = 32,
X	bHJustMask = 192,	/* two bits:  64 + 128 */
X	bVJustMask = 768,	/* two bits:  256 + 512 */
X	bPicMask = 1024
X};
X
X
X/*	blob drawing modes	*/
X
Xenum
X{
X	normalDraw = 1,		/* draw blob normally */
X	dimDraw = 2			/* draw dimmed blob */
X};
X
X/*	blob part codes	*/
X
Xenum
X{
X	inStatBlob = 1,			 /* static region */
X	inDragBlob = 2,			 /* drag region */
X	inFullBlob = 3			 /* entire blob */
X};
X
X/*
X	special max glue count - no limit
X*/
X
X# define	infiniteGlue	0x8000
X
X
X/*
X	BlobClick return codes
X*/
X
Xenum
X{
X	/* 0 = nothing done */
X	bcGlue = 1,		/* donor blob glued to receptor */
X	bcUnglue,		/* glob unglued from receptor */
X	bcXfer,			/* glob transferred from one receptor to another */
X	bcDup,			/* glob duplicated from one receptor onto another */
X	bcSwap			/* globs of two receptors swapped */
X};
X
X
X/*
X	Messages passed by BlobClick to advisory functions
X*/
X
Xenum
X{
X	advDClick,		/* click in donor */
X	advRClick,		/* click in receptor */
X	advGlue,		/* glue transaction proposed */
X	advUnglue,		/* unglue transaction proposed */
X	advXfer,		/* transfer transaction proposed */
X	advDup,			/* duplicate transaction proposed */
X	advSwap			/* swap transaction proposed */
X};
X
X
X/*	DragGrayRgn result code for bad drag - Inside Mac is wrong! */
X
X# define	badDragResult	0x80008000L
X
X
X/*
X	BlobRecord structure
X	
X	flags:
X	bit 0: 1 = enabled, 0 = disabled
X	bit 1: 1 = frozen, 0 = thawed (1/0)
X	bit 2: 1 = static region is dimmed, 0 = normal
X	bit 3: 1 = drag region is dimmed, 0 = normal
X	bit 4: 1 = need explicit match, 0 = don't
X
X	fzflags:
X	bit 2: 1 = static region was dimmed before freeze, 0 = was normal
X	bit 3: 1 = drag region was dimmed before freeze, 0 = was normal
X
X*/
X
Xtypedef struct BlobRecord
X{
X	int			flags;			/* flags word */
X	int			fzFlags;		/* freeze flags word */
X	union						/* pic if bPicMask flag word bit set*/
X	{							/* proc if bit clear */
X		PicHandle	bPic;		/* blob picture (and original frame) */
X		ProcPtr		bDrawProc;	/* blob drawing procedure */
X	} bPicProc;
X	RgnHandle	statRgn;		/* current static region */
X	RgnHandle	dragRgn;		/* current drag region */
X	Rect		statRect;		/* original static region frame */
X	Rect		dragRect;		/* original drag region frame */
X	int			glueMax;		/* maximum times can glue to others */
X	int			glueCount;		/* number of times glued to others */
X	struct MatchRecord	**matches;	/* set of valid matches */
X	struct BlobRecord	**glob;	 /* currently glued blob */
X	long		bRefCon;		/* reference value */
X	struct BlobRecord	**nextBlob;	 /* next blob in set */
X} BlobRecord, *BlobPtr, **BlobHandle;
X
X
Xtypedef struct MatchRecord
X{
X	BlobHandle			mBlob;			/* blob that matches */
X	struct MatchRecord	**nextMatch;	/* next match record */
X} MatchRecord, *MatchPtr, **MatchHandle;
X
X
Xtypedef struct BlobSetRecord
X{
X	BlobHandle				firstBlob;		/* first Blob of set */
X	BlobHandle				lastBlob;		/* last Blob of set */
X	struct BlobSetRecord	**nextBlobSet;	/* next blob set */
X} BlobSetRecord, *BlobSetPtr, **BlobSetHandle;
X
X
X/*
X	Pseudo-functions
X*/
X
X# define	FirstBlob(bSet)		((**(bSet)).firstBlob)
X# define	LastBlob(bSet)		((**(bSet)).lastBlob)
X# define	NextBlob(b)			((**(b)).nextBlob)
X# define	SetBRefCon(b,val)	((**(b)).bRefCon = (long) (val))
X# define	GetBRefCon(b)		((long) (**(b)).bRefCon)
X# define	BStatBox(b)			((**((**(b)).statRgn)).rgnBBox)
X# define	BDragBox(b)			((**((**(b)).dragRgn)).rgnBBox)
X# define	BGlob(b)			((**(b)).glob)
X# define	FirstBMatch(b)		((**((**(b)).matches)).mBlob)
X
X
X/*
X	Functions returning non-integral values
X*/
X
XBlobHandle		GetBlobHandle ();
XBlobHandle		NewBlob ();
XBlobSetHandle	NewBlobSet ();
XBoolean 		BlobQuiet ();
XBoolean 		BlobSetQuiet ();
XBoolean 		InBlobMatchSet ();
Xlong			DTrackBlob ();
Xlong			TrackBlob ();
XBoolean			BlobDimmed ();
XBoolean			BlobActive ();
XBoolean			BlobFrozen ();
XBoolean			BlobEnabled ();
XBoolean			CanGlue ();
XBoolean			PicBlob ();
XRgnHandle		BCalcRegion ();
XBoolean			BTrackMouse ();
X
X# endifSHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BMgr/BMgrCalcRegion.c
X# include	"BlobMgr.h"
X
X
X/*
X	Return copy of the region corresponding to the part code.  The
X	caller is responsible for disposing of the region that is returned.
X*/
X
XRgnHandle BCalcRegion (b, partCode)
XBlobHandle	b;
Xint			partCode;
X{
XRgnHandle	rgn;
X
X	rgn = NewRgn ();
X	if (partCode == inDragBlob)
X		CopyRgn ((**b).dragRgn, rgn);
X	else
X	{
X		CopyRgn ((**b).statRgn, rgn);
X		if (partCode == inFullBlob)
X			UnionRgn ((**b).dragRgn, rgn, rgn);
X	}
X	return (rgn);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BMgr/BMgrClick.c
X/*
X	BlobClick and support routines. BlobClick is the basic blob
X	transaction handler.  Other routines and variables are used
X	to modify the way BlobClick functions.
X
X
X	unglueZoom determines whether BlobClick will zoom an outline of the
X	receptor drag region back to the donor when a donor is unglued
X	from a receptor by double-clicking.
X
X	badDragZoom determines whether the outline of a dragged donor will
X	be zoomed back where it was dragged from if it's not dragged
X	somewhere it can be glued to.
X
X	The permission booleans control the types of transactions that
X	BlobClick is allowed to perform:
X
X	ungluePerm is true if double-clicking detaches globs from receptors.	
X	xferPerm is true if globs can be transferred between receptors.	
X	swapPerm is true if globs can be swapped between receptors.
X	dupPerm is true if globs can be duplicated onto other receptors.
X	replacePerm is true if transfers, swaps and duplications can cause
X	a receptor's glob to be replaced by another.  Note that if
X	replacePerm is false, transfers and duplications can only be made
X	to empty receptors, and swaps fail altogether.
X
X	Swaps take precedence over duplications, and both take precedence
X	over transfers, if two or more of these flags are on.  All are
X	subject to the value of the replacement flag, as noted above.
X
X	lastWhen and lastWhere are for double-click detection.
X	If lastWhen is set to 0, the next click will not be interpreted
X	as a double-click.  Since that's how it's initialized, BlobClick
X	never mistakes the first click passed to it for a double-click.
X
X	BlobClick only saves the click time and location when the user
X	clicks in a receptor blob drag region and releases the mouse without
X	moving it, since that's the only time a double-click is relevant.
X
X	bcAdvise is the BlobClick filter function.  If it's nil, BlobClick
X	does all the work itself.  If bcFilter is set to the address of
X	some function, that function is consulted in certain circumstances
X	to see whether to continue processing or not.  If the filter returns
X	false, BlobClick terminates early.
X
X	bcResult holds the result of the last call to BlobClick.  db1,
X	db2, rb1 and rb2 are set to indicate which blobs were involved in
X	any transaction that occurs (these are known as the cast (as in
X	cast of thousands) of the transaction).  The result code and the
X	cast may be obtained by the host program with the BClickResult
X	routine, and have meanings as follows:
X
X	Glue: db1 = donor glued, rb1 = receptor glued to, db2 = donor replaced by
X		db1 (nil if none), rb2 nil.
X	Unglue: db1 = donor unglued, rb1 = receptor unglued from, db2, rb2 nil.
X	Transfer: db1 = donor transferred, rb1 = source receptor,
X		rb2 = destination receptor, db2 = donor replaced by db1 (nil if none).
X	Duplication: same as transfer, except db1 = donor duplicated.
X	Swap: db1 = donor originally on rb1, db2 = donor originally on rb2,
X		rb1 = source receptor, rb2 = dest receptor.
X
X	The result code and the cast are undefined if a filter function
X	causes BlobClick to terminate early.
X
X	srcRect and dstRect are used by BlobClick and BadDrag to keep
X	track of how to do zoomback on bad drags.
X*/
X
X# include	"BlobMgr.h"
X
X
Xstatic Boolean	unglueZoom = true;
Xstatic Boolean	badDragZoom = true;
X
Xstatic Boolean	ungluePerm = true;
Xstatic Boolean	xferPerm = true;
Xstatic Boolean	replacePerm = true;
Xstatic Boolean	dupPerm = false;
Xstatic Boolean	swapPerm = true;
X
X
Xstatic long		lastWhen = 0L;
Xstatic Point	lastWhere;
X
Xstatic Boolean	(*bcAdvise)() = nil;
X
Xstatic int			bcResult;
Xstatic BlobHandle	db1;
Xstatic BlobHandle	db2;
Xstatic BlobHandle	rb1;
Xstatic BlobHandle	rb2;
X
Xstatic Rect			srcRect, dstRect;
X
X
X/*
X	Set or get the flags determining zoomback behavior on bad drags
X	and unglue transactions
X*/
X
XSetBCZoomFlags (uGlueZoom, bDragZoom)
XBoolean uGlueZoom, bDragZoom;
X{
X	unglueZoom = uGlueZoom;
X	badDragZoom = bDragZoom;
X}
X
X
XGetBCZoomFlags (uGlueZoom, bDragZoom)
XBoolean *uGlueZoom, *bDragZoom;
X{
X	*uGlueZoom = unglueZoom;
X	*bDragZoom = badDragZoom;
X}
X
X
X/*
X	Set or get the flags determining transaction permissions
X*/
X
XSetBCPermissions (canUnglue, canXfer, canDup, canSwap, canRep)
XBoolean canUnglue, canXfer, canDup, canSwap, canRep;
X{
X	ungluePerm = canUnglue;
X	xferPerm = canXfer;
X	dupPerm = canDup;
X	swapPerm = canSwap;
X	replacePerm = canRep;
X}
X
X
XGetBCPermissions (canUnglue, canXfer, canDup, canSwap, canRep)
XBoolean *canUnglue, *canXfer, *canDup, *canSwap, *canRep;
X{
X	*canUnglue = ungluePerm;
X	*canXfer = xferPerm;
X	*canDup = dupPerm;
X	*canSwap = swapPerm;
X	*canRep = replacePerm;
X}
X
X
X/*
X	Set or get the address of the BlobClick advisory filter routine.
X	Pass nil to SetBCFilter to turn the filter off.
X*/
X
XSetBCAdvisory (p)
XBoolean	(*p)();
X{
X	bcAdvise = p;
X}
X
X
XGetBCAdvisory (p)
XBoolean (**p)();
X{
X	*p = bcAdvise;
X}
X
X
X/*
X	FindReceptor is called with the point at which the mouse was released
X	after a donor or a receptor's glob was dragged.  It returns true if
X	the mouse was released in a receptor that has an undimmed drag region
X	and either (i) has no glob, or (ii) has a glob but replacement
X	permission is on.  Otherwise it returns false.
X*/
X
Xstatic Boolean FindReceptor (thePoint, rSet, r)
XPoint			thePoint;	/* point at which mouse released */
XBlobSetHandle	rSet;		/* receptor set */
XBlobHandle		*r;			/* return receptor hit in this */
X{
X	return (FindBlob (thePoint, rSet, r)
X			&& GetBDrawMode (*r, inDragBlob) == normalDraw
X			&& (BGlob (*r) == nil || replacePerm));
X}
X
X
X/*
X	BlobClick blob transaction handler
X*/
X
XBlobClick (thePt, t, dSet, rSet)
XPoint			thePt;
Xlong			t;
XBlobSetHandle	dSet, rSet;
X{
XBlobHandle			d, r1, r2;
XPoint				thePoint;
Xregister long		dragDelta;
Xregister Boolean	badDrag = true;	/* assume the worst */
X
X	thePoint = thePt;			/* do setup:  make local copy of point */
X	bcResult = 0;				/* and initialize status variables */
X	db1 = db2 = rb1 = rb2 = nil;
X
X/*
X	Check for double-click if unglue permission is on.  If so and both
X	clicks were in drag region of a non-dim receptor that has a glob
X	glued to it, unglue the glob.  (Note that the hit-tests only work
X	if the blob is not dimmed - which is as things should be.)
X*/
X	if (ungluePerm && t - lastWhen <= GetDblTime ())
X	{
X		if (rSet != nil
X			&& FindBlob (thePoint, rSet, &r1) == inDragBlob
X			&& TestBlob (r1, lastWhere) == inDragBlob)
X		{
X			if (bcAdvise == nil || (*bcAdvise) (advUnglue, r1))
X			{
X				db1 = BGlob (r1);
X				rb1 = r1;
X				bcResult = bcUnglue;
X
X				if (unglueZoom)
X					ZUnglueGlob (r1);
X				else
X					UnglueGlob (r1);
X			}
X		}
X		lastWhen = 0L;
X		return;
X	}
X
X	lastWhen = 0L;
X
X/*
X	See if the mouse was clicked in a donor blob.  If so, drag an
X	outline around.  If the dragged outline ends up somewhere it
X	can be glued to, do so, else zoom the outline back if appropriate.
X*/
X
X	if (dSet != nil && FindBlob (thePoint, dSet, &d) == inDragBlob)
X	{
X		if (bcAdvise != nil && (*bcAdvise) (advDClick, d) == false)
X			return;		/* advisory says "quit" */
X
X		dragDelta = DTrackBlob (d, inDragBlob, thePoint);
X		if (dragDelta != badDragResult && dragDelta != 0)
X		{
X			thePoint.h += LoWord (dragDelta);
X			thePoint.v += HiWord (dragDelta);
X			srcRect = dstRect = BDragBox (d);
X			OffsetRect (&dstRect, LoWord (dragDelta), HiWord (dragDelta));
X			if (rSet != nil && FindReceptor (thePoint, rSet, &r1))
X			{
X				if (bcAdvise == nil || (*bcAdvise) (advGlue, r1))
X				{
X					db1 = d;
X					db2 = BGlob (r1);
X					rb1 = r1;
X					bcResult = bcGlue;
X					GlueGlob (d, r1);
X					badDrag = false;
X				}
X			}
X			if (badDrag && badDragZoom)
X				ZoomRect (&dstRect, &srcRect);
X		}
X	}
X
X/*
X	Mouse was not clicked in a donor.  If it was clicked in a receptor,
X	a glob may have been dragged back to the donor, or to another
X	receptor, so get ready to process possible unglue or inter-receptor
X	transaction.  Can quit early if no receptor set was given
X	(rSet = nil) or no inter-receptor or unglue transactions are allowed.
X*/
X	else if (rSet != nil && (ungluePerm || xferPerm || swapPerm || dupPerm))
X	{
X		if (FindBlob (thePoint, rSet, &r1) == inDragBlob && BGlob (r1) != nil)
X		{
X			if (bcAdvise != nil && (*bcAdvise) (advRClick, r1) == false)
X				return;		/* advisory says "quit" */
X
X/*
X	If the mouse is released without being moved, then save the click
X	info, since it might be the first click of a double-click.  There's
X	no need to check any further for a possible transaction since the
X	glob wasn't dragged anywhere.
X*/
X			if ((dragDelta = DTrackBlob (r1, inDragBlob, thePoint)) == 0L)
X			{
X				lastWhen = t;		/* save click info for possible */
X				lastWhere = thePt;	/* double-click next time */
X			}
X			else if (dragDelta != badDragResult)
X			{
X				thePoint.h += LoWord (dragDelta);
X				thePoint.v += HiWord (dragDelta);
X
X/*
X	Was the glob dragged back to it's owner?  If so, unglue it if
X	unglue permission is on.  Can't use TestBlob, 'cause that'll
X	be false if the donor is dimmed.
X*/
X				d = BGlob (r1);
X				if (ungluePerm && BlobActive (d)
X						&& (PtInRgn (thePoint, (**d).dragRgn)
X							|| PtInRgn (thePoint, (**d).statRgn)))
X				{
X					if (bcAdvise == nil || (*bcAdvise) (advUnglue, r1))
X					{
X						db1 = d;
X						rb1 = r1;
X						bcResult = bcUnglue;
X						UnglueGlob (r1);	/* no zooming */
X					}
X					return;
X				}
X
X				srcRect = dstRect = BDragBox (r1);
X				OffsetRect (&dstRect, LoWord (dragDelta), HiWord (dragDelta));
X
X				if (FindReceptor (thePoint, rSet, &r2) && r1 != r2)
X				{
X
X	/*
X		Now know where the glob was dragged, so possibly have some kind
X		of inter-receptor transaction.  If replaces aren't allowed, then
X		don't continue unless the receptor that was dragged to has no glob.
X		Otherwise do whichever of swapping, duplicating or transferring is
X		allowed.  Precedence is in that order if more than one of them is
X		allowed.
X	*/
X					rb1 = r1;			/* set cast now, but they */
X					rb2 = r2;			/* won't be meaningful if */
X					db1 = BGlob (r1);	/* no transaction is performed */
X					db2 = BGlob (r2);
X					if (db2 != nil && swapPerm)
X					{
X						if (bcAdvise == nil || (*bcAdvise) (advSwap, r2))
X						{
X							SwapGlob (r1, r2);
X							bcResult = bcSwap;
X							badDrag = false;
X						}
X					}
X					else if (dupPerm)
X					{
X						if (CanGlue (db1))
X						{
X							if (bcAdvise == nil || (*bcAdvise) (advDup, r2))
X							{
X								DupGlob (r1, r2);	/* duplicate blob */
X								bcResult = bcDup;
X								badDrag = false;
X							}
X						}
X					}
X					else if (xferPerm)
X					{
X						if (bcAdvise == nil || (*bcAdvise) (advXfer, r2))
X						{
X							TransferGlob (r1, r2);	/* transfer blob */
X							bcResult = bcXfer;
X							badDrag = false;
X						}
X					}
X				}
X				if (badDrag && badDragZoom)
X					ZoomRect (&dstRect, &srcRect);
X			}
X		}
X	}
X}
X
X
X/*
X	Result result code of last call to BlobClick.
X*/
X
XBClickResult ()
X{
X	return (bcResult);
X}
X
X
X/*
X	Result cast of characters involved in last call to BlobClick.
X*/
X
XBClickCast (d1, d2, r1, r2)
XBlobHandle	*d1, *d2, *r1, *r2;
X{
X	*d1 = db1;
X	*d2 = db2;
X	*r1 = rb1;
X	*r2 = rb2;
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BMgr/BMgrDrag.c
X# include	<WindowMgr.h>
X# include	"BlobMgr.h"
X
X
X/* -------------------------------------------------------------------- */
X/*					Blob Tracking and Dragging Routines					*/
X/* -------------------------------------------------------------------- */
X
X
X/*
X	Blob dragging variables.  See discussion of DragGrayRgn in
X	the WIndow Manager section of Inside Mac.  The defaults for the
X	limit and slop rects are inappropriate and really should be set
X	by the application.
X*/
X
XRect	blobLimitRect = { -30000, -30000, 30000, 30000 };
XRect	blobSlopRect = { -30000, -30000, 30000, 30000 };
Xint		blobAxis = noConstraint;
X
X
X/*	Set blob dragging limit and slop rectangles	*/
X
XSetBDragRects (limitRect, slopRect)
XRect	*limitRect, *slopRect;
X{
X	blobLimitRect = *limitRect;
X	blobSlopRect = *slopRect;
X}
X
X
X/*	get current blob dragging limit and slop rectangles	*/
X
XGetBDragRects (limitRect, slopRect)
XRect	*limitRect, *slopRect;
X{
X	*limitRect = blobLimitRect;
X	*slopRect = blobSlopRect;
X}
X
X
X/*	Set blob dragging axis constraints	*/
X
XSetBDragAxis (axis)
Xint	axis;
X{
X	blobAxis = axis;
X}
X
X
X/*	Get current blob dragging axis constraints	*/
X
XGetBDragAxis ()
X{
X	return (blobAxis);
X}
X
X
X/*
X	Track blob by dragging an outline of the indicated part around
X	until the mouse button is released.	Return the difference between
X	the starting and ending x and y coordinates in the low and high
X	order words of the result.
X*/
X
X
Xlong TrackBlob (b, partCode, startPoint, limitRect, slopRect, axis)
XBlobHandle	b;
Xint			partCode;
XPoint		startPoint;
XRect		*limitRect, *slopRect;
Xint			axis;
X{
XRgnHandle	rgn;
XRect		limit, bounds;
Xlong		result;
X
X	rgn = BCalcRegion (b, partCode);
X/*
X	adjust the limit rectangle so the outline of the dragged regiopn
X	always fits completely within the bounds rectangle
X*/
X	limit = *limitRect;
X	bounds = (**rgn).rgnBBox;
X	limit.left += startPoint.h - bounds.left;
X	limit.top += startPoint.v - bounds.top;
X	limit.right -= bounds.right - startPoint.h - 1;
X	limit.bottom -= bounds.bottom - startPoint.v - 1;
X	
X	result = DragGrayRgn (rgn, startPoint, &limit, slopRect, axis, nil);
X	DisposeRgn (rgn);
X	return (result);
X}
X
X
X/*
X	Track a blob, using the default limit and slop rects
X*/
X
Xlong DTrackBlob (b, partCode, startPoint)
XBlobHandle	b;
Xint			partCode;
XPoint		startPoint;
X{
X
X	return (TrackBlob (b, partCode, startPoint,
X								&blobLimitRect, &blobSlopRect, blobAxis));
X}
X
X
X/*
X	Drag a blob by tracking it, and then moving it to the point
X	where the mouse button was released.
X*/
X
XDragBlob (b, startPoint, limitRect, slopRect, axis)
XBlobHandle	b;
XPoint		startPoint;
XRect		*limitRect, *slopRect;
Xint			axis;
X{
Xlong	result;
X
X	result = TrackBlob (b, inFullBlob, startPoint,
X							limitRect, slopRect, axis);
X
X	if ((result != badDragResult) && (result != 0))
X		OffsetBlob (b, inFullBlob, LoWord (result), HiWord (result));
X}
X
X
XDDragBlob (b, startPoint)
XBlobHandle	b;
XPoint		startPoint;
X{
X	DragBlob (b, startPoint, &blobLimitRect, &blobSlopRect, blobAxis);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BMgr/BMgrDraw.c
X/* --------------------------------------------------------------------- */
X/*					Blob Manager Low-level Drawing Routines				 */
X/* --------------------------------------------------------------------- */
X
X# include	"BlobMgr.h"
X
X
X
X/*
X	Blob dimming parameters.  dimPat and dimMode are the pattern and
X	drawing mode used to dim out blobs.  The initial pattern is gray.
X*/
X
Xstatic Pattern	dimPat = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
Xstatic int		dimMode = patBic;
X
Xstatic RgnHandle	oldClipRgn;
X
X
X/*
X	Set or get the pattern to be used to dim blobs
X*/
X
XSetBDimInfo (p, mode)
XPattern	*p;
Xint		mode;
X{
X	BlockMove (p, &dimPat, sizeof (Pattern));
X	dimMode = mode;
X}
X
XGetBDimInfo (p, mode)
XPattern	*p;
Xint		*mode;
X{
X	BlockMove (&dimPat, p, sizeof (Pattern));
X	*mode = dimMode;
X}
X
X
X/*
X	Set the clipping to the given region of the given blob.  Return
X	a handle to the region, or nil if the region is empty and doesn't
X	need to be drawn.  The handle should not be disposed of by the
X	caller - it's a copy of the handle, not a copy of the region.
X	If the handle returned is not nil, call RestoreDrawClip after doing
X	the drawing to restore the clipping properly.
X*/
X
Xstatic RgnHandle SetDrawClip (b, partCode)
XBlobHandle	b;
Xint			partCode;
X{
Xregister RgnHandle	drawRgn, newClipRgn;
X
X	drawRgn = (partCode == inDragBlob ? (**b).dragRgn : (**b).statRgn);
X	if (EmptyRgn (drawRgn))	/* don't bother if fail here! */
X		return (nil);
X
X	oldClipRgn = NewRgn ();
X	newClipRgn = NewRgn ();
X	GetClip (oldClipRgn);
X	SectRgn (drawRgn, oldClipRgn, newClipRgn);
X	SetClip (newClipRgn);
X	DisposeRgn (newClipRgn);
X	return (drawRgn);
X}
X
X
Xstatic RestoreDrawClip ()
X{
X	SetClip (oldClipRgn);				/* restore original clipping */
X	DisposeRgn (oldClipRgn);
X}
X
X
X/*
X	Dim the given region.
X*/
X
Xstatic DimRgn (rgn)
XRgnHandle	rgn;
X{
XPenState	ps;
X
X	GetPenState (&ps);			/* save current pen state */
X	PenPat (dimPat);
X	PenMode (dimMode);
X	PaintRgn (rgn);
X	SetPenState (&ps);			/* restore pen state */
X}
X
X
X/*
X	Given a picture and a rectangle corresponding to a portion of the picture
X	frame DrawBlobPic draws the picture in the given part of the given blob,
X	accounting for size and location differences.	Any portion of sRect
X	lying outside of the picture's frame will not be drawn.
X	The partCode must be inDragBlob or inFullBlob.
X
X	The drawing is clipped to the region the be drawn
X	(respecting current clipping).
X*/
X
Xstatic DrawBlobPic (b, partCode, p, srcRect)
XBlobHandle	b;
Xint			partCode;
XPicHandle	p;
XRect		*srcRect;
X
X{
Xregister RgnHandle	rgn;
XRect		dstRect, pFrame;
X
X	rgn = SetDrawClip (b, partCode);
X	if (p != nil && rgn != nil)		/* don't bother if fail here! */
X	{
X		pFrame = (**p).picFrame;			/* map frame to correct size */
X		dstRect = (**rgn).rgnBBox;			/* and location in relation */
X		MapRect (&pFrame, srcRect, &dstRect);	/* to region to be drawn */
X		DrawPicture (p, &pFrame);
X		if (GetBDrawMode (b, partCode) == dimDraw)	/* region is dimmed */
X			DimRgn (rgn);
X	}
X	if (rgn != nil)
X		RestoreDrawClip ();				/* restore original clipping */
X}
X
X
X/*
X	Draw a blob using a drawing procedure.  bDst is the blob to be drawn,
X	partCode specifies the region of bDst to draw (either inDragBlob or
X	inStatBlob).  bSrc is the blob whose region is to be drawn in the
X	specified region of bDst, and proc is the drawing procedure to use.
X	bSrc is different than bDst if partCode is inDragBlob and bDst has
X	a glob.
X*/
X
Xstatic CallBDrawProc (bDst, bSrc, proc, partCode)
XBlobHandle	bDst, bSrc;
XProcPtr		proc;
Xint			partCode;
X{
Xregister RgnHandle	rgn;
X
X	rgn = SetDrawClip (bDst, partCode);
X	if (proc != nil && rgn != nil)
X	{
X		(*proc) (bDst, bSrc, partCode);
X		if (GetBDrawMode (bDst, partCode) == dimDraw)	/* region is dimmed */
X			DimRgn (rgn);
X	}
X	if (rgn != nil)
X		RestoreDrawClip ();				/* restore original clipping */
X}
X
X
X/*
X	DrawBlob draws the indicated part of the blob (the entire blob
X	if partCode is inFullBlob).
X
X	The blob must be enabled.  If draw mode is dimDraw then draw
X	it dimmed.
X*/
X
X
XDrawBlob (b, partCode)
XBlobHandle	b;
Xint			partCode;
X
X{
Xregister BlobHandle	b2;
Xregister PicHandle	pic;
XRect		srcFrame;
X
X	if (BlobEnabled (b))
X	{
X		if ((partCode == inStatBlob) || (partCode == inFullBlob))
X		{
X			if (PicBlob (b))
X			{
X				srcFrame = (**b).statRect;
X				DrawBlobPic (b, inStatBlob, (**b).bPicProc.bPic, &srcFrame);
X			}
X			else
X				CallBDrawProc (b, b, (**b).bPicProc.bDrawProc, inStatBlob);
X		}
X
X		if ((partCode == inDragBlob) || (partCode == inFullBlob))
X		{
X		/*
X			Set b2 to the blob that should have it's drag region drawn
X			in b's drag region.  If b has no glob, then it's b.
X		*/
X			if ((b2 = BGlob (b)) == nil)
X				b2 = b;
X			if (PicBlob (b2))
X			{
X				pic = (**b2).bPicProc.bPic;	/* picture to draw */
X				srcFrame = (**b2).dragRect;	/* part of picture to draw */
X				DrawBlobPic (b, inDragBlob, pic, &srcFrame);
X			}
X			else
X				CallBDrawProc (b, b2, (**b2).bPicProc.bDrawProc, inDragBlob);
X		}
X	}
X}
X
X
XDrawBlobSet (bSet)
XBlobSetHandle	bSet;
X{
X	BlobLoopProc2 (&DrawBlob, bSet, inFullBlob);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BMgr/BMgrFlags.c
X# include	"BlobMgr.h"
X
X
X/* -------------------------------------------------------------------- */
X/*					 Blob Flag Manipulation Routines					*/
X/*																		*/
X/*	These routines operate only on the content of the blob state fields.*/
X/*	They do NOT do any redrawing or change the display in any way.		*/
X/*																		*/
X/* -------------------------------------------------------------------- */
X
X
XSetBlobFlags (b, bitMask)
XBlobHandle	b;
Xint			bitMask;
X{
X	(**b).flags |= bitMask;
X}
X
X
XClearBlobFlags (b, bitMask)
XBlobHandle	b;
Xint			bitMask;
X{
X	(**b).flags &= ~bitMask;			/* what's the operator here? */
X}
X
X
X/*
X	Test the function result to be sure it's equal to the bitMask
X	passed in, if exact match is required.
X*/
X
XTestBlobFlags (b, bitMask)
XBlobHandle	b;
Xint			bitMask;
X{
X	return ((**b).flags & bitMask);
X}
X
X
XEnableBlob (b)
XBlobHandle	b;
X{
X	SetBlobFlags (b, bEnableMask);
X}
X
X
XEnableBlobSet (bSet)
XBlobSetHandle	bSet;
X{
X	BlobLoopProc1 (&EnableBlob, bSet);
X}
X
X
XDisableBlob (b)
XBlobHandle	b;
X{
X	ClearBlobFlags (b, bEnableMask);
X}
X
X
XDisableBlobSet (bSet)
XBlobSetHandle	bSet;
X{
X	BlobLoopProc1 (&DisableBlob, bSet);
X}
X
X
X
XGetBDrawMode (b, partCode)
XBlobHandle	b;
Xint			partCode;
X{
Xint		mask;
X
X	mask = 0;
X	switch (partCode)
X	{
X		case inDragBlob: mask = bDragModeMask; break;
X		case inStatBlob: mask = bStatModeMask; break;
X	}
X	return (TestBlobFlags (b, mask) == mask ? dimDraw : normalDraw);
X}
X
X
XSetBDrawMode (b, partCode, mode)
XBlobHandle	b;
Xint			partCode;
Xint			mode;
X{
Xint		mask;
X
X	switch (partCode)
X	{
X		case inFullBlob: mask = bDrawModeMask; break;
X		case inDragBlob: mask = bDragModeMask; break;
X		case inStatBlob: mask = bStatModeMask; break;
X	}
X	if (mode == dimDraw)
X		SetBlobFlags (b, mask);
X	else
X		ClearBlobFlags (b, mask);
X}
X
X
XGetFzBDrawMode (b, partCode)
XBlobHandle	b;
Xint			partCode;
X{
Xint		mask;
X
X	mask = 0;
X	switch (partCode)
X	{
X		case inDragBlob: mask = bDragModeMask; break;
X		case inStatBlob: mask = bStatModeMask; break;
X	}
X	return (((**b).fzFlags & mask) == mask ? dimDraw : normalDraw);
X}
X
X
X
XBoolean BlobDimmed (b, partCode)
XBlobHandle	b;
Xint			partCode;
X{
Xint		bitMask;
X
X	switch (partCode)
X	{
X		case inFullBlob: bitMask = bDrawModeMask; break;
X		case inStatBlob: bitMask = bStatModeMask; break;
X		case inDragBlob: bitMask = bDragModeMask; break;
X	}
X	return (TestBlobFlags (b, bitMask) == bitMask);
X}
X
X
XBoolean BlobEnabled (b)
XBlobHandle	b;
X{
X	return (TestBlobFlags (b, bEnableMask) == bEnableMask);
X}
X
X
XBoolean BlobFrozen (b)
XBlobHandle	b;
X{
X	return (TestBlobFlags (b, bFreezeMask) == bFreezeMask);
X}
X
X
X/*
X	Active = enabled, but not frozen.
X*/
X
XBoolean BlobActive (b)
XBlobHandle	b;
X{
X	return (TestBlobFlags (b, bEnableMask | bFreezeMask) == bEnableMask);
X}
X
X
X/*
X	Return true if the blob can be glued to another blob.  This is true
X	if the blob is infinitely gluable or the current glue count is less
X	than the blob's maximum glue count.
X*/
X
XBoolean CanGlue (b)
XBlobHandle	b;
X{
Xint		glueMax;
X
X	glueMax = GetBGlueMax (b);
X	return (glueMax == infiniteGlue || glueMax > (**b).glueCount);
X}
X
X
X/*
X	Return true if the blob is a picture blob, false if it's a
X	procedure blob
X*/
X
XBoolean PicBlob (b)
XBlobHandle	b;
X{
X	return (TestBlobFlags (b, bPicMask) == bPicMask);
X}SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BMgr/BMgrFreeze.c
X# include	"BlobMgr.h"
X
X
XFreezeBlob (b)
XBlobHandle	b;
X{
X	if (!BlobFrozen (b))
X	{
X		SetBlobFlags (b, bFreezeMask);
X		(**b).fzFlags = ((**b).flags & (bDrawModeMask));
X	}
X}
X
X
XFreezeBlobSet (bSet)
XBlobSetHandle	bSet;
X{
X	BlobLoopProc1 (&FreezeBlob, bSet);
X}
X
X
XThawBlob (b)
XBlobHandle	b;
X{
X	if (BlobFrozen (b))
X	{
X		ClearBlobFlags (b, bFreezeMask);	/* unfreeze blob */
X		HiliteBlob (b, inStatBlob, GetFzBDrawMode (b, inStatBlob));
X		HiliteBlob (b, inDragBlob, GetFzBDrawMode (b, inDragBlob));
X	}
X}
X
X
XThawBlobSet (bSet)
XBlobSetHandle	bSet;
X{
X	BlobLoopProc1 (&ThawBlob, bSet);
X}
X
X
X/*
X	Display enabled quiet blobs with drawing mode quietMode, display
X	enabled noisy blobs with drawing mode noisyMode.	Freezes all enabled
X	blobs, so should be balanced with a call to ThawBlobs.
X*/
X
X
XBlobFeedback (bSet, quietMode, noisyMode)
XBlobSetHandle	bSet;
Xint				quietMode, noisyMode;
X{
XBlobHandle	b;
X
X	for (b = FirstBlob (bSet); b != nil; b = NextBlob (b))
X	{
X		FreezeBlob (b);
X		HiliteBlob (b, inFullBlob, (BlobQuiet (b) ? quietMode : noisyMode));
X	}
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BMgr/BMgrHideShow.c
X# include	"BlobMgr.h"
X
X
X
X/*
X	If blob not already hidden, hide it by filling both the bounds
X	box of each region with current grafport's background pattern,
X	and accumulate the boxes into the update region.
X*/
X
XHideBlob (b)
XBlobHandle	b;
X{
XGrafPtr	thePort;
XRect	r;
X
X	if (BlobEnabled (b))			/* ignore if already disabled */
X	{
X		DisableBlob (b);
X		GetPort (&thePort);
X
X		r = BStatBox (b);
X		FillRect (&r, &thePort->bkPat);
X		InvalRect (&r);
X
X		r = BDragBox (b);
X		FillRect (&r, &thePort->bkPat);
X		InvalRect (&r);
X	}
X}
X
X
XHideBlobSet (bSet)
XBlobSetHandle	bSet;
X{
X	BlobLoopProc1 (&HideBlob, bSet);
X}
X
X
X/*
X	If blob is not already enabled, show it.
X*/
X
XShowBlob (b)
XBlobHandle	b;
X{
X	if (BlobEnabled (b) == false)		/* ignore if already enabled */
X	{
X		EnableBlob (b);
X		DrawBlob (b, inFullBlob);
X	}
X}
X
X
XShowBlobSet (bSet)
XBlobSetHandle	bSet;
X{
X	BlobLoopProc1 (&ShowBlob, bSet);
X}
SHAR_EOF
exit
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads