📄 cocoa_gui.mm
字号:
{ return rect;}@end@implementation AmbulantView- (id)initWithFrame:(NSRect)frameRect{ [super initWithFrame: frameRect]; ambulant_window = NULL; transition_surface = NULL; transition_tmpsurface = NULL; transition_count = 0; fullscreen_count = 0; fullscreen_previmage = NULL; fullscreen_oldimage = NULL; fullscreen_engine = NULL; return self;}- (void)dealloc { if (transition_surface) [transition_surface release]; transition_surface = NULL; if (transition_tmpsurface) [transition_tmpsurface release]; transition_tmpsurface = NULL; [super dealloc];}- (NSRect) NSRectForAmbulantRect: (const ambulant::lib::rect *)arect{#ifdef USE_COCOA_BOTLEFT float bot_delta = NSMaxY([self bounds]) - arect->bottom(); return NSMakeRect(arect->left(), bot_delta, arect->width(), arect->height());#else return NSMakeRect(arect->left(), arect->top(), arect->width(), arect->height());#endif}- (ambulant::lib::rect) ambulantRectForNSRect: (const NSRect *)nsrect{#ifdef USE_COCOA_BOTLEFT float top_delta = NSMaxY([self bounds]) - NSMaxY(*nsrect); ambulant::lib::rect arect = ambulant::lib::rect( ambulant::lib::point(int(NSMinX(*nsrect)), int(top_delta)), ambulant::lib::size(int(NSWidth(*nsrect)), int(NSHeight(*nsrect))));#else ambulant::lib::rect arect = ambulant::lib::rect( ambulant::lib::point(int(NSMinX(*nsrect)), int(NSMinY(*nsrect))), ambulant::lib::size(int(NSWidth(*nsrect)), int(NSHeight(*nsrect)))); #endif return arect;}- (void) asyncRedrawForAmbulantRect: (NSRectHolder *)arect{ NSRect my_rect = [arect rect]; [arect release]; AM_DBG NSLog(@"AmbulantView.asyncRedrawForAmbulantRect: self=0x%x rect=(%f,%f,%f,%f)", self, NSMinX(my_rect), NSMinY(my_rect), NSMaxX(my_rect), NSMaxY(my_rect)); [self setNeedsDisplayInRect: my_rect];}- (void) syncDisplayIfNeeded: (id) dummy{// [self displayIfNeeded]; [self display];}- (void)drawRect:(NSRect)rect{ AM_DBG NSLog(@"AmbulantView.drawRect: self=0x%x rect=(%f,%f,%f,%f)", self, NSMinX(rect), NSMinY(rect), NSMaxX(rect), NSMaxY(rect));// redraw_lock.enter(); if (!ambulant_window) { AM_DBG NSLog(@"Redraw AmbulantView: NULL ambulant_window"); } else { // If we have seen transitions we always redraw the whole view if (transition_count) rect = [self bounds]; ambulant::lib::rect arect = [self ambulantRectForNSRect: &rect]; [self _screenTransitionPreRedraw]; ambulant_window->redraw(arect); [self _screenTransitionPostRedraw];#ifdef DUMP_REDRAW // Debug code: dump the contents of the view into an image [self dumpToImageID: "redraw"];#endif [self _releaseTransitionSurface]; }// redraw_lock.leave();}- (void)setAmbulantWindow: (ambulant::gui::cocoa::cocoa_window *)window{// [[self window] setAcceptsMouseMovedEvents: true]; ambulant_window = window;}- (void)ambulantWindowClosed{ AM_DBG NSLog(@"ambulantWindowClosed called"); ambulant_window = NULL; // XXXX Should we close the window too? Based on preference?}- (bool)isAmbulantWindowInUse{ return (ambulant_window != NULL);}- (BOOL)isFlipped{#ifdef USE_COCOA_BOTLEFT return false;#else return true;#endif}- (void)mouseDown: (NSEvent *)theEvent{ NSPoint where = [theEvent locationInWindow]; where = [self convertPoint: where fromView: nil]; if (!NSPointInRect(where, [self bounds])) { AM_DBG NSLog(@"mouseDown outside our frame"); return; } AM_DBG NSLog(@"mouseDown at ambulant-point(%f, %f)", where.x, where.y); ambulant::lib::point amwhere = ambulant::lib::point((int)where.x, (int)where.y); if (ambulant_window) ambulant_window->user_event(amwhere);}- (void)mouseMoved: (NSEvent *)theEvent{ NSPoint where = [theEvent locationInWindow]; where = [self convertPoint: where fromView: nil]; if (!NSPointInRect(where, [self bounds])) { AM_DBG NSLog(@"mouseDown outside our frame"); return; } AM_DBG NSLog(@"mouseMoved at ambulant-point(%f, %f)", where.x, where.y); ambulant::lib::point amwhere = ambulant::lib::point((int)where.x, (int)where.y); [[NSApplication sharedApplication] sendAction: SEL("resetMouse:") to: nil from: self]; if (ambulant_window) ambulant_window->user_event(amwhere, 1); // XXX Set correct cursor [[NSApplication sharedApplication] sendAction: SEL("fixMouse:") to: nil from: self];}- (void) dumpToImageID: (char *)ident{ [self lockFocus]; NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithFocusedViewRect: [self bounds]]; [self unlockFocus]; [self dump: image toImageID: ident];}- (void) dump: (id)image toImageID: (char *)ident{ static int seqnum = 0; NSString *filename = [NSString stringWithFormat: DUMP_IMAGES_FORMAT, seqnum++, ident]; NSData *tiffrep = [image TIFFRepresentation]; [tiffrep writeToFile: filename atomically: NO]; AM_DBG NSLog(@"dump:toImageFile: created %@", filename);}- (BOOL)wantsDefaultClipping{#ifdef DUMP_REDRAW return NO;#else return (transition_count == 0);#endif}- (void) incrementTransitionCount{ transition_count++; AM_DBG NSLog(@"incrementTransitionCount: count=%d", transition_count);}- (void) decrementTransitionCount{ assert(transition_count > 0); transition_count--; AM_DBG NSLog(@"decrementTransitionCount: count=%d", transition_count); // XXXX Should we delete transition_surface? // XXXX Should we delete transition_tmpsurface?}- (NSImage *)getTransitionSurface{ if (!transition_surface) { // It does not exist yet. Create it. transition_surface = [self _getOnScreenImage]; [transition_surface retain]; } return transition_surface;}- (void)_releaseTransitionSurface{ if (transition_surface) { [transition_surface release]; transition_surface = NULL; }}- (NSImage *)getTransitionTmpSurface{ if (!transition_tmpsurface) { // It does not exist yet. Create it. transition_tmpsurface = [self _getOnScreenImage]; [transition_tmpsurface retain]; [transition_tmpsurface setFlipped: NO]; } return transition_tmpsurface;}- (NSImage *)_getOnScreenImage{ NSRect bounds = [self bounds]; NSSize size = NSMakeSize(NSWidth(bounds), NSHeight(bounds)); NSImage *rv = [[NSImage alloc] initWithSize: size]; [self lockFocus]; NSBitmapImageRep *bits = [[NSBitmapImageRep alloc] initWithFocusedViewRect: [self bounds]]; [self unlockFocus]; [rv addRepresentation: [bits autorelease]]; [rv setFlipped: YES];#ifdef DUMP_TRANSITION [self dump: rv toImageID: "oldsrc"];#endif rv = [rv autorelease]; return rv;}- (NSImage *)getOnScreenImageForRect: (NSRect)bounds{ NSSize size = NSMakeSize(NSWidth(bounds), NSHeight(bounds)); NSImage *rv = [[NSImage alloc] initWithSize: size]; [self lockFocus]; NSBitmapImageRep *bits = [[NSBitmapImageRep alloc] initWithFocusedViewRect: bounds]; [self unlockFocus]; [rv addRepresentation: [bits autorelease]]; [rv setFlipped: YES];#ifdef DUMP_TRANSITION [self dump: rv toImageID: "oldsrc"];#endif rv = [rv autorelease]; return rv;}- (NSImage *)getTransitionOldSource{ if (fullscreen_count && fullscreen_oldimage) return fullscreen_oldimage; return [self _getOnScreenImage];}- (NSImage *)getTransitionNewSource{ NSRect bounds = [self bounds]; NSSize size = NSMakeSize(NSWidth(bounds), NSHeight(bounds)); NSImage *rv = [[NSImage alloc] initWithSize: size]; [rv setFlipped: YES]; [transition_surface lockFocus]; NSBitmapImageRep *bits = [[NSBitmapImageRep alloc] initWithFocusedViewRect: [self bounds]]; [transition_surface unlockFocus]; [rv addRepresentation: [bits autorelease]];#ifdef DUMP_TRANSITION [self dump: rv toImageID: "newsrc"];#endif rv = [rv autorelease]; return rv;}- (void) startScreenTransition{ AM_DBG NSLog(@"startScreenTransition"); if (fullscreen_count) NSLog(@"Warning: multiple Screen transitions in progress"); fullscreen_count++; if (fullscreen_oldimage) [fullscreen_oldimage release]; fullscreen_oldimage = fullscreen_previmage; fullscreen_previmage = NULL;}- (void) endScreenTransition{ AM_DBG NSLog(@"endScreenTransition"); assert(fullscreen_count > 0); fullscreen_count--;}- (void) screenTransitionStep: (ambulant::smil2::transition_engine *)engine elapsed: (ambulant::lib::transition_info::time_type)now{ AM_DBG NSLog(@"screenTransitionStep %d", (int)now); assert(fullscreen_count > 0); fullscreen_engine = engine; fullscreen_now = now;}- (void) _screenTransitionPreRedraw{ if (fullscreen_count == 0) return; // XXX setup drawing to transition surface AM_DBG NSLog(@"_screenTransitionPreRedraw: setup for transition redraw"); [[self getTransitionSurface] lockFocus];}- (void) _screenTransitionPostRedraw{ if (fullscreen_count == 0 && fullscreen_oldimage == NULL) { // Neither in fullscreen transition nor wrapping one up. // Take a snapshot of the screen and return. if (fullscreen_previmage) [fullscreen_previmage release]; fullscreen_previmage = [[self _getOnScreenImage] retain]; /*DBG [self dump: fullscreen_previmage toImageID: "fsprev"]; */ return; } if (fullscreen_oldimage == NULL) { // Just starting a new fullscreen transition. Get the // background bits from the snapshot saved during the previous // redraw. fullscreen_oldimage = fullscreen_previmage; fullscreen_previmage = NULL; } // Do the transition step, or simply copy the bits // if no engine available. AM_DBG NSLog(@"_screenTransitionPostRedraw: bitblit"); [[self getTransitionSurface] unlockFocus];// /*DBG*/ [self dump: [self getTransitionOldSource] toImageID: "fsold"];// /*DBG*/ [self dump: [self getTransitionNewSource] toImageID: "fsnew"]; NSRect bounds = [self bounds]; if (fullscreen_engine) { [[self getTransitionOldSource] drawInRect: bounds fromRect: bounds operation: NSCompositeCopy fraction: 1.0]; fullscreen_engine->step(fullscreen_now); } else { AM_DBG NSLog(@"_screenTransitionPostRedraw: no screen transition engine");// [[self getTransitionNewSource] compositeToPoint: NSZeroPoint// operation: NSCompositeCopy]; [[self getTransitionNewSource] drawInRect: bounds fromRect: bounds operation: NSCompositeCopy fraction: 1.0]; } if (fullscreen_count == 0) { // Finishing a fullscreen transition. AM_DBG NSLog(@"_screenTransitionPostRedraw: cleanup after transition done"); if (fullscreen_oldimage) [fullscreen_oldimage release]; fullscreen_oldimage = NULL; fullscreen_engine = NULL; }}@end#endif // __OBJC__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -