Re: How to flash two rectangles in a frame?
Re: How to flash two rectangles in a frame?
- Subject: Re: How to flash two rectangles in a frame?
- From: Graham Cox <email@hidden>
- Date: Sun, 15 Mar 2009 23:00:18 +1100
On 14/03/2009, at 7:42 PM, Philip Kime wrote:
I am trying to work out how to flash two rects in a frame. I have it
working with one rect using the view cacheImageInRect method but this
only works on one rect. I tried putting two such calls in serial but
the second one doesn't work for some (optimisation?) reason. Then I
tried copying and modifying the code from the GNUstep implementation
of the method but this is too hard for me since I'm not a serious ObjC
or Cocoa programmer - the method is designed to be run as an instance
method and the code wasn't suitable for just calling directly in a
routine. I never got it to work. So, I subclassed NSWindow and tried
adding a "cacheImagesInRects" method but again, I couldn't get this to
work - the "restoreImagesInRects" never seemed to restore anything.
I also tried just colouring the rects with
NSRectFillListWithColorsUsingOperation, hoping to be able to use
NSCompositeLighter and then NSCompositeDarker to reverse the change.
Again, no luck - it almost looked right with a simple DeviceWhite 50%
alpha fill and then Lighter/Darker change but not quite. Any other
colour (which I needed) just failed to reverse and the rects stayed in
the "on" flash state.
I've spent far, far too much time on this now and I realise I'm just
not knowledgeable enough in ObjC or Cocoa. So, any hints on how to
approach flashing two rectangles at the same time? This was so easy in
Carbon - InvRect().
It's not precisely clear what you want here - what do you mean by
"flash".
I'll assume you want to draw two rects in a view for a short period
then erase them again. In response to what though?
Quartz graphics aren't comparable to QuickDraw graphics because a)
they are not pixel-based and b) they support alpha channels which
makes simply "inverting" a rect have little meaning. However, if my
assumption above is reasonable, doing this is straightforward.
In Cocoa, flagging an update and responding to it by drawing occur in
two separate phases. You could set this up like this (warning: typed
into Mail):
@interface FlashView : NSView
{
BOOL rectsVisible;
NSRect rectA;
NSRect rectB;
}
- (IBAction) performFlashRectangles:(id) sender;
- (void) endFlash;
@end
#define FLASH_PERIOD 1.0
//-----------------------------------------------------------
@implementation FlashView
- (id) initWithFrame:(NSRect) frame
{
self = [super initWithFrame:frame];
if( self )
{
rectA = NSMakeRect( 10, 10, 100, 100 );
rectB = NSMakeRect( 120, 10, 100, 100 );
}
return self;
}
- (void) drawRect:(NSRect) updateRect
{
[[NSColor whiteColor] set];
NSRectFill( updateRect );
if( rectsVisible )
{
// set rectA colour here
[[NSColor redColor] set];
NSRectFill( rectA );
// set rect B colour here
[[NSColor blueColor] set];
NSRectFill( rectB );
}
}
- (IBAction) performFlashRectangles:(id) sender
{
rectsVisible = YES;
[self setNeedsDisplay:YES];
[self performSelector:@selector(endFlash) withObject:nil
afterDelay:FLASH_PERIOD];
}
- (void) endFlash
{
rectsVisible = NO;
[self setNeedsDisplay:YES];
}
//--------------------------------------------------------------------------
To trigger a "flash", the -performFlashRectangles: method is called -
you could connect this to a menu or button for example. This requests
a refresh which causes the display to draw the rectangles. It also
starts a timer which calls the -endFlash method which also requests a
refresh but sets the "rectsVisible" flag to NO.
If you wanted the rects to flash on and off continuously, you can
probably see how you could use a timer or delayed method call to
accomplish that.
--Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden