Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!ucsd!ucbvax!hoptoad!tim From: tim@hoptoad.uucp (Tim Maroney) Newsgroups: comp.sys.mac.programmer Subject: Re: Marquee Help? Message-ID: <9518@hoptoad.uucp> Date: 6 Jan 90 08:10:10 GMT References: <18304@dartvax.Dartmouth.EDU> Reply-To: tim@hoptoad.UUCP (Tim Maroney) Organization: Eclectic Software, San Francisco Lines: 224 In article <18304@dartvax.Dartmouth.EDU> sean@eleazar.dartmouth.edu (Sean P. Nolan) writes: >I saw on here recently a passing mention that someone was using code that >produced the MacPaint-like Marquee around a selection. The Johnny Carson theme >comes to mind. But I have been trying, off-and-on, to figure out how to do >just that, given a selection rectangle and a nifty slot to do its thing in >my Event loop. > >If anybody has the ah-ha insight on how to do this, I'd really appreciate a >note. Currently I shoved the problem aside and just InvertRect the selection, >which is uuuuuuuugly. Might as well just post dwb's code that I got from a local BBS: ; ; (c) Copyright 1987, David W. Berry ; case object string pascal load 'MacStuff' export MarqueeRect, MoveMarqueeRect patterns record entry,decr marqueePat dc.l $0f87c3e1, $f0783c1e shiftPat dc.l $88442211, $88442211 endr ; ; Frame rectangle, using marquee pattern. The rect is drawn in xor mode. ; This procedure should be called to draw the marquee initially, then ; MoveMarqueeRect should be called repeatedly to move the pattern. ; Finally, call MarqueeRect again to erase the marquee. The display ; will end up the same as it was before. ; MarqueeRect proc export Frame record {a6link},decr rect ds.l 1 return ds.l 1 a6link ds.l 1 state ds.b psRec locals equ * endr with Frame link a6,#locals pea state(a6) _GetPenState _PenNormal pea patterns.marqueePat _PenPat move.w #patXor,-(a7) _PenMode move.l rect(a6),-(a7) _FrameRect pea state(a6) _SetPenState unlk a6 rts endproc ; ; Frame rectangle, using pattern that moves the marquee. Then shift ; the pattern and the marquee pattern, to keep the two in sync. ; This procedure must be called repeatedly to achieve the effect of ; motion. ; MoveMarqueeRect proc export Frame record {a6link},decr rect ds.l 1 return ds.l 1 a6link ds.l 1 state ds.b psRec locals equ * endr with Frame link a6,#locals pea state(a6) _GetPenState _PenNormal pea patterns.shiftPat _PenPat move #patXor,-(a7) _PenMode move.l rect(a6),-(a7) _FrameRect pea state(a6) _SetPenState ; shift the marquee pattern 1 slot to the left lea patterns.marqueePat,a0 bsr.s rotate ; likewise the shift pattern lea patterns.shiftPat,a0 bsr.s rotate unlk a6 rts rotate: move.l (a0),d1 move.l 4(a0),d0 rol.l #8,d0 rol.l #8,d1 move.b d0,d2 move.b d1,d0 move.b d2,d1 move.l d1,(a0) move.l d0,4(a0) rts endproc end End of quoted code marquee.a. Here's MPW C code I use for the same effect. I'm afraid it's rather environment-dependent, but you should still be able to break it to your will. static void RotatePatterns(Pattern marquee, Pattern shift) { unsigned char c; c = marquee[0]; BlockMove(marquee + 1, marquee, 7); marquee[7] = c; c = shift[0]; BlockMove(shift + 1, shift, 7); shift[7] = c; } static void click(WindowPtr window, DocStorage **storage, EventRecord *event, Boolean *changed, Boolean *selected) { Point start, now; Rect r, r2; short tmp; DocInfo doc; Pattern marquee, shift; PenState pen; #pragma unused (changed) unselect(window, storage); GetDocInfo(window, &doc); start = now = event->where; GetPenState(&pen); PenNormal(); BlockMove((Ptr)(*storage)->marquee, (Ptr)marquee, 8); BlockMove((Ptr)(*storage)->shift, (Ptr)shift, 8); PenPat(marquee); PenMode(patXor); SetRect(&r, start.h, start.v, now.h, now.v); FrameRect(&r); while (WaitMouseUp()) { PenPat(shift); FrameRect(&r); RotatePatterns(marquee, shift); GetMouse(&now); SetRect(&r2, start.h, start.v, now.h, now.v); if (r2.left > r2.right) { tmp = r2.left; r2.left = r2.right; r2.right = tmp; } if (r2.top > r2.bottom) { tmp = r2.top; r2.top = r2.bottom; r2.bottom = tmp; } if (EqualRect(&r, &r2)) continue; PenPat(marquee); FrameRect(&r); FrameRect(&r2); r = r2; } if (*selected = !EmptyRect(&r)) OffsetRect(&r, GetCtlValue(doc.hScroll), GetCtlValue(doc.vScroll)); else { PenPat(marquee); FrameRect(&r); SetRect(&r, 0, 0, 0, 0); } BlockMove((Ptr)marquee, (Ptr)(*storage)->marquee, 8); BlockMove((Ptr)shift, (Ptr)(*storage)->shift, 8); (*storage)->selRect = r; SetPenState(&pen); } static void idle(WindowPtr window, DocStorage **storage) { Pattern marquee, shift; Rect r; PenState pen; DocInfo doc; r = (*storage)->selRect; if (EmptyRect(&r)) return; GetDocInfo(window, &doc); GetPenState(&pen); PenNormal(); BlockMove((Ptr)(*storage)->marquee, (Ptr)marquee, 8); BlockMove((Ptr)(*storage)->shift, (Ptr)shift, 8); PenPat(shift); PenMode(patXor); OffsetRect(&r, -GetCtlValue(doc.hScroll), -GetCtlValue(doc.vScroll)); FrameRect(&r); RotatePatterns(marquee, shift); BlockMove((Ptr)marquee, (Ptr)(*storage)->marquee, 8); BlockMove((Ptr)shift, (Ptr)(*storage)->shift, 8); SetPenState(&pen); } And in Rez, the patterns are: resource 'PAT#' (33) { { $"0f 87 c3 e1 f0 78 3c 1e" , $"88 44 22 11 88 44 22 11" } }; -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com "Gorbachev is returning to the heritage of the great Lenin" - Ronald Reagan