sean@eleazar.dartmouth.edu (Sean P. Nolan) (01/05/90)
Hi ho... 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. Thanks! --- Sean +----------------------------------------------------------------------------+ | Sean P. Nolan | Net: Sean_Nolan@Mac.Dartmouth.EDU | "Let's face it: | | Dartmouth College | | IBM is no fun." | | Hinman Box 2658 | SCALP 'EM! | :::::::::: | | Hanover, NH 03755 | | John C. Dvorak | +----------------------------------------------------------------------------+
mtoy@sgi.com (Michael Toy) (01/06/90)
One way to get something marquee like, would be to use a set of patterns of diagonal stripes the following example will draw a cheap marquee rectangle, looping forever: char p0[] = { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }; char p1[] = { 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11, 0x88 }; char p2[] = { 0x22, 0x11, 0x88, 0x44, 0x22, 0x11, 0x88, 0x11 }; char p3[] = { 0x11, 0x88, 0x44, 0x22, 0x11, 0x88, 0x11, 0x22 }; marqueeRect(Rect *pRect) { int patNum = 0; char *patterns[4]; patterns[0] = p0; patterns[1] = p2; patterns[2] = p2; patterns[3] = p3; PenMode(patXor); /* I'm not sure this is either the correct function or parameter name */ for (;;) { long t = TickCount(); PenPat(patterns[patNum++]); patNum &= 3; FrameRect(pRect); /* Draw a rectangle */ while (TickCount() - t < 4) /* Wait a bit */ ; FrameRect(pRect); /* Undraw the rectangle */ } PenNormal(); }
tim@hoptoad.uucp (Tim Maroney) (01/06/90)
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
lsr@Apple.COM (Larry Rosenstein) (01/09/90)
> PenMode(patXor); /* I'm not sure this is either the correct If you are doing this in a bitmap, then you should use patCopy. patXOR might look better in a structured graphics program, where there is always a lot of white space. (If you use patCopy then to erase the marquee you have to redraw the contents of the rectangle.0 > PenPat(patterns[patNum++]); > patNum &= 3; > FrameRect(pRect); /* Draw a rectangle */ > while (TickCount() - t < 4) /* Wait a bit */ Another way to do this is to choose the pattern based on the value of TickCount % 4 (or TickCount % 8 if you use 8 patterns). The advantage is that the ants will move at the same speed regardless of the size of the rectangle. The disadvantage is that you may get jerky motion if your loop can't keep up. -- Larry Rosenstein, Object Specialist Apple Computer, Inc. 20525 Mariani Ave, MS 46-B Cupertino, CA 95014 AppleLink:Rosenstein1 domain:lsr@Apple.COM UUCP:{sun,voder,nsc,decwrl}!apple!lsr
dwb@archer.apple.com (David W. Berry) (01/09/90)
In article <9518@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes: >; >; (c) Copyright 1987, David W. Berry >; I might point out that where I a real jerk, this is a violation of the copyright above. However, permission is granted for any non-commercial usage of the code. Those of you that wish to use it in a commercial product can either contact me, or transliterate yourself... It's not that difficult once you understand the concepts. BTW, this is derived from a C version posted sometime ago by somebody else, I turned it into assembler to speed it up (significantly as it turns out)