[futurebasic] Re: Animated CICON

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : March 1998 : Group Archive : Group : All Groups

From: Rick Brown <rbrown@...>
Date: Sun, 15 Mar 1998 11:21:59 -0600
Michel wrote:
> I animate a CICON by USR GETPICT the background, placing the CICON, then
> restoring the background with PICTURE, moving the position, and so on.
> It works fine until I have another window on the top of the CICON
> rectangle. USR GETPICT then records the top window.
> The CICON is a slow moving object (a ship on a map) so I don't need to
> animate when another window is masking the CICON rectangle. How can I
> prevent this to happen when: 1) one of my application window is on the
> top (Preference window, etc) or, 2) a Finder/other appl is on the top?

I would do something like this:

I would make use of the "visRgn" field of the window's data structure. 
visRgn keeps track of which part of the window's content region is
currently visible.  The visRgn is affected by anything which hides all
or part of the content, such as when another window obscures your
window.  You can get a handle to the visRgn& like this:

  GET WINDOW windowID, wptr&
  theVisRgn& = wptr&.visRgn&

You can then do tests to see whether or not the icon rectangle lies
entirely within the visRgn.  If it does, then you can animate.  If the
icon rectangle is completely or partially obscured, then you don't
animate.

First, create a couple of new regions to work with:

  iconRgn& = FN NEWRGN
  scratchRgn& = FN NEWRGN

Then, whenever you want to do the test, do this:

  'Make iconRgn& equal in size/shape/location to current iconRect:
  CALL RECTRGN(iconRgn&, iconRect)
  'Subtract intersection of visRgn and iconRgn& from iconRgn&,
  'And put the result into scratchRgn&
  CALL DIFFRGN(iconRgn&, wptr&.visRgn&, scratchRgn&)
  'If scratchRgn& is now empty, then iconRgn& is entirely inside
  'visRgn.  But if scratchRgn& is not empty, then iconRgn& is
  'at least partially obscured:
  LONG IF FN EMPTYRGN(scratchRgn&)
    iconObscured = _false
  XELSE
    iconObscured = _zTrue
  END IF

Note that iconObscured will be set to _zTrue whenever any part of the
icon's rectangle is not visible.  This includes not only cases where
your window is obscured by another window, but also when the user hides
your application, or "windowshades" the window up, or moves the window
partially offscreen, or resizes it, etc.

You can then inhibit animation whenever iconObscured is _zTrue.  The
only difficuly I see is in cases where the icon intersects the edge of
the window (but is otherwise completely visible): in that case
iconObscured will be set to _zTrue, but you may still wish to animate. 
If this presents a problem, then instead of testing whether iconRgn& is
completely visible, you can test whether the intersection of iconRgn&
with the window's content region is completely visible:

  CALL RECTRGN(iconRgn&, iconRect)
  'Get the part of iconRgn& which is inside the content region:
  CALL SECTRGN(iconRgn&, wptr&.contRgn&, scratchRgn&)
  LONG IF FN EMPTYRGN(scratchRgn&)
    'The icon was _completely_ outside of the window:
    iconObscured = _zTrue
  XELSE
    'ScratchRgn& now represents the portion of the icon rect
    'which is actually inside the window.  Test whether any
    'of _that_ region is otherwise obscured.
    CALL DIFFRGN(scratchRgn&, wptr&.visRgn&, scratchRgn&)
    LONG IF FN EMPTYRGN(scratchRgn&)
      iconObscured = _false
    XELSE
      iconObscured = _zTrue
    END IF
  END IF

If you calculate iconObscured this way, then it will be set to _false if
the icon rectangle is completely visible, or is partially off the edge
of the window but is otherwise completely visible.  IconObscured will be
set to _zTrue if the icon is partially or wholly obscured for any other
reason.

Hope this helps (and I hope I haven't put any bugs into this untested
code!)

- Rick