home *** CD-ROM | disk | FTP | other *** search
- /* Window definition ('WDEF') to draw floating "windoid" windows. There are
- several variation codes (see comments in header).
-
- 931215 aih drag bar is erased if window is unhilited
- 931207 aih added zoom and grow boxes
- 931114 aih created */
-
- #include "WindoidWDEF.h"
-
- /* return absolute value of x */
- #define abs(x) ((x) < 0 ? -(x) : x)
-
- /* rectangles for the various parts of a window */
- struct rects {
- Rect border; /* border around structure area */
- Rect drag; /* drag area */
- Rect goaway; /* go away area */
- Rect zoom; /* zoom area */
- Rect grow; /* grow area */
- };
-
- /*----------------------------------------------------------------------------*/
- /* rectangle calculation */
- /*----------------------------------------------------------------------------*/
-
- /* return structure rectangle */
- static void getstructure(WindowPeek win, Rect *structure)
- {
- /* assert: win->visible == true */
- *structure = (**win->strucRgn).rgnBBox;
- }
-
- /* return content rectangle */
- static void getcontent(WindowPeek win, Rect *content)
- {
- /* assert: win->visible == true */
- *content = (**win->contRgn).rgnBBox;
- }
-
- /* given a window's content rectangle, calculates its structure rectangle
- (works even with invisible windows) */
- static void calcstructure(short var, WindowPeek win, Rect *content)
- {
- InsetRect(content, -kWindoidBorderSize, -kWindoidBorderSize);
- content->bottom += kWindoidShadowSize;
- content->right += kWindoidShadowSize;
- if (WindoidDragLeft(var))
- content->left -= kWindoidDragSize + 1;
- else if (WindoidDragTop(var))
- content->top -= kWindoidDragSize + 1;
- }
-
- /* given a window calculate its content rectangle (works even with
- invisible windows) */
- static void calccontent(short var, WindowPeek win, Rect *content)
- {
- GrafPtr port = (GrafPtr) win;
-
- *content = port->portRect;
- OffsetRect(content, -port->portBits.bounds.left, -port->portBits.bounds.top);
- }
-
- /* calculate the rectangles of the window (e.g., drag, grow, zoom, etc.),
- given the structure and content rectangles */
- static void calcrects2(short var, WindowPeek win, struct rects *rects,
- const Rect *structure, const Rect *content)
- {
- rects->border = *structure;
- rects->border.bottom -= kWindoidShadowSize;
- rects->border.right -= kWindoidShadowSize;
- rects->drag = rects->border;
- InsetRect(&rects->drag, kWindoidBorderSize, kWindoidBorderSize);
- if (WindoidDragLeft(var)) {
- rects->drag.right = rects->drag.left + kWindoidDragSize;
- rects->goaway.top = rects->drag.top + 8;
- rects->goaway.left = rects->drag.left + 1;
- rects->zoom.top = rects->drag.bottom - 7 - kWindoidZoomSize;
- rects->zoom.left = rects->drag.left + 1;
- }
- else {
- rects->drag.bottom = rects->drag.top + kWindoidDragSize;
- rects->goaway.top = rects->drag.top + 1;
- rects->goaway.left = rects->drag.left + 8;
- rects->zoom.top = rects->drag.top + 1;
- rects->zoom.left = rects->drag.right - 7 - kWindoidZoomSize;
- }
- rects->goaway.bottom = rects->goaway.top + kWindoidGoAwaySize;
- rects->goaway.right = rects->goaway.left + kWindoidGoAwaySize;
- rects->zoom.bottom = rects->zoom.top + kWindoidZoomSize;
- rects->zoom.right = rects->zoom.left + kWindoidZoomSize;
- rects->grow = *content;
- rects->grow.top = rects->grow.bottom - kWindoidGrowSize;
- rects->grow.left = rects->grow.right - kWindoidGrowSize;
- OffsetRect(&rects->grow, 1, 1);
- }
-
- /* calculate the rectangles of the window (e.g., drag, grow, zoom, etc.) */
- static void calcrects(short var, WindowPeek win, struct rects *rects)
- {
- Rect structure, content;
-
- getstructure(win, &structure);
- getcontent(win, &content);
- calcrects2(var, win, rects, &structure, &content);
- }
-
- /*----------------------------------------------------------------------------*/
- /* pattern manipulation */
- /*----------------------------------------------------------------------------*/
-
- /* invert bits of pattern so it alligns nicely on the screen */
- static void patinvert(Pattern pat)
- {
- pat[0] = ~pat[0];
- pat[2] = ~pat[2];
- pat[4] = ~pat[4];
- pat[6] = ~pat[6];
- }
-
- /* rotate bits of pattern so it alligns nicely on the screen */
- static void patrotate(Pattern pat)
- {
- unsigned long *shift = (unsigned long *) pat;
- shift[1] = shift[0] >>= 8;
- }
-
- /*----------------------------------------------------------------------------*/
- /* zoom window utilities */
- /*----------------------------------------------------------------------------*/
-
- /* Return true if the window is in the standard state
- (i.e., is zoomed, see IM-IV, p10), otherwise it must
- be in the user state so set the user state to the
- window's content rectangle. */
- static Boolean zoomed(WindowPeek win)
- {
- Rect content;
- Rect stdState;
- Boolean result = false;
-
- /* assert: win->spareFlag == true && win->dataHandle != NULL */
- getcontent(win, &content);
- stdState = (**(WStateData**)win->dataHandle).stdState;
- result =
- (abs(content.top - stdState.top) <= kWindoidZoomMargin &&
- abs(content.left - stdState.left) <= kWindoidZoomMargin &&
- abs(content.bottom - stdState.bottom) <= kWindoidZoomMargin &&
- abs(content.right - stdState.right) <= kWindoidZoomMargin);
- if (! result)
- (**(WStateData**)win->dataHandle).userState = content;
- return(result);
- }
-
- /*----------------------------------------------------------------------------*/
- /* window definition routines */
- /*----------------------------------------------------------------------------*/
-
- /* draw window; param must be short, not long, see technote */
- static long draw(short var, WindowPeek win, short param)
- {
- Pattern pat;
- PenState pen;
- struct rects rects;
-
- if (win->visible) {
- calcrects(var, win, &rects);
- GetPenState(&pen);
- PenNormal();
- switch (param) {
- case wNoHit:
-
- /* draw border */
- FrameRect(&rects.border);
-
- /* draw shadow */
- MoveTo(rects.border.right, rects.border.top + 2);
- LineTo(rects.border.right, rects.border.bottom);
- LineTo(rects.border.left + 2, rects.border.bottom);
-
- /* draw drag region */
- if (WindoidDrag(var)) {
-
- /* draw drag pattern */
- if (win->hilited) {
- StuffHex(pat, (unsigned char *) "\pAA00AA00AA00AA00");
- if (rects.border.left & 1) patinvert(pat);
- if (rects.border.top & 1) patrotate(pat);
- FillRect(&rects.drag, pat);
- }
- else
- EraseRect(&rects.drag);
-
- /* draw line between drag and content regions */
- if (WindoidDragLeft(var))
- MoveTo(rects.drag.right, rects.drag.top);
- else if (WindoidDragTop(var))
- MoveTo(rects.drag.left, rects.drag.bottom);
- LineTo(rects.drag.right, rects.drag.bottom);
-
- /* draw go away region */
- if (win->goAwayFlag) {
- InsetRect(&rects.goaway, -1, -1);
- EraseRect(&rects.goaway);
- InsetRect(&rects.goaway, 1, 1);
- FrameRect(&rects.goaway);
- }
-
- /* draw zoom region */
- if (WindoidZoom(var)) {
- InsetRect(&rects.zoom, -1, -1);
- EraseRect(&rects.zoom);
- InsetRect(&rects.zoom, 1, 1);
- FrameRect(&rects.zoom);
- rects.zoom.bottom -= kWindoidZoomSize / 2 - 1;
- rects.zoom.right -= kWindoidZoomSize / 2 - 1;
- FrameRect(&rects.zoom);
- }
- }
- break;
- case wInGoAway:
- InsetRect(&rects.goaway, 1, 1);
- InvertRect(&rects.goaway);
- break;
- case wInZoomIn:
- case wInZoomOut:
- InsetRect(&rects.zoom, 1, 1);
- InvertRect(&rects.zoom);
- break;
- }
- SetPenState(&pen);
- }
- return(0);
- }
-
- /* return area hit by mouse */
- static long hit(short var, WindowPeek win, long param)
- {
- Rect structure, content;
- Point where = *(Point *) ¶m;
- long result = wNoHit;
- struct rects rects;
-
- getstructure(win, &structure);
- getcontent(win, &content);
- if (PtInRect(where, &structure)) {
- calcrects(var, win, &rects);
- if (WindoidGrow(var) && PtInRect(where, &rects.grow))
- result = wInGrow;
- else if (PtInRect(where, &content))
- result = wInContent;
- else if (WindoidDrag(var)) {
- if (win->goAwayFlag && PtInRect(where, &rects.goaway))
- result = wInGoAway;
- else if (WindoidZoom(var) && PtInRect(where, &rects.zoom))
- result = zoomed(win) ? wInZoomIn : wInZoomOut;
- else if (PtInRect(where, &rects.drag))
- result = wInDrag;
- }
- }
- return(result);
- }
-
- /* calculate the window's content and structure regions and
- update zoom state */
- static long calc(short var, WindowPeek win, long param)
- {
- Rect area;
-
- calccontent(var, win, &area);
- RectRgn(win->contRgn, &area);
- calcstructure(var, win, &area);
- RectRgn(win->strucRgn, &area);
- if (WindoidZoom(var))
- (void) zoomed(win);
- return(0);
- }
-
- /* initialize the window */
- static long new(short var, WindowPeek win, long param)
- {
- Rect content;
-
- if (WindoidZoom(var)) {
- win->spareFlag = true;
- win->dataHandle = NewHandleClear(sizeof(WStateData));
- calccontent(var, win, &content);
- (**(WStateData**)win->dataHandle).userState = content;
- (**(WStateData**)win->dataHandle).stdState = content;
- }
- return(0);
- }
-
- /* dispose of private store */
- static long dispose(short var, WindowPeek win, long param)
- {
- if (WindoidZoom(var) && win->dataHandle)
- DisposHandle(win->dataHandle);
- return(0);
- }
-
- /* draw lines for tracking the size box */
- static long grow(short var, WindowPeek win, long param)
- {
- Rect content;
- Rect structure;
- struct rects rects;
-
- /* calculate rectangles based on
- rectangle parameter */
- structure = content = *(Rect *) param;
- calcstructure(var, win, &structure);
- calcrects2(var, win, &rects, &structure, &content);
-
- /* draw line around structure region */
- FrameRect(&structure);
-
- /* draw line between drag and content regions */
- if (WindoidDrag(var)) {
- if (WindoidDragLeft(var))
- MoveTo(rects.drag.right, rects.drag.top);
- else if (WindoidDragTop(var))
- MoveTo(rects.drag.left, rects.drag.bottom);
- LineTo(rects.drag.right, rects.drag.bottom);
- }
-
- /* draw lines around size box and scroll bar areas */
- MoveTo(rects.grow.left, structure.bottom);
- LineTo(rects.grow.left, WindoidDragTop(var) ? rects.drag.bottom :
- structure.top);
- MoveTo(structure.right, rects.grow.top);
- LineTo(structure.left, rects.grow.top);
- return(0);
- }
-
- /* draw the grow icon */
- static long drawgrow(short var, WindowPeek win, long param)
- {
- struct rects rects;
- GrafPtr port;
-
- GetPort(&port);
- SetPort((WindowPtr) win);
- calcrects(var, win, &rects);
- FrameRect(&rects.grow);
- InsetRect(&rects.grow, 2, 2);
- FrameRect(&rects.grow);
- SetPort(port);
- return(0);
- }
-
- pascal long main(short var, WindowPtr window, short msg, long param)
- {
- WindowPeek win = (WindowPeek) window;
-
- switch (msg) {
- case wDraw: return(draw(var, win, param));
- case wHit: return(hit(var, win, param));
- case wCalcRgns: return(calc(var, win, param));
- case wNew: return(new(var, win, param));
- case wDispose: return(dispose(var, win, param));
- case wGrow: return(grow(var, win, param));
- case wDrawGIcon: return(drawgrow(var, win, param));
- }
- return(0);
- }
-