diff options
author | Kevin Walzer <kw@codebykevin.com> | 2015-04-09 02:00:59 (GMT) |
---|---|---|
committer | Kevin Walzer <kw@codebykevin.com> | 2015-04-09 02:00:59 (GMT) |
commit | d10216afc1dcddd76f93bcdbb6e87bdca8dc7453 (patch) | |
tree | 3d2c1b4ec2054fbe9fd8a6a5cd948ad5cc6d8c71 /macosx/tkMacOSXDraw.c | |
parent | f801eafc556ad7c6648d5da223a6563c99b998ca (diff) | |
download | tk-d10216afc1dcddd76f93bcdbb6e87bdca8dc7453.zip tk-d10216afc1dcddd76f93bcdbb6e87bdca8dc7453.tar.gz tk-d10216afc1dcddd76f93bcdbb6e87bdca8dc7453.tar.bz2 |
Re-working of internal Cocoa widget drawing routines, especially when resizing; fix rendering of scrollbar when resized or clipped; cleanup of button metrics; thanks to Marc Culler for extensive patches
Diffstat (limited to 'macosx/tkMacOSXDraw.c')
-rw-r--r-- | macosx/tkMacOSXDraw.c | 95 |
1 files changed, 72 insertions, 23 deletions
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index c1ffdf8..3f51d00 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -222,7 +222,8 @@ XCopyArea( } if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) { - TkMacOSXDbgMsg("Failed to setup drawing context."); + return; + /*TkMacOSXDbgMsg("Failed to setup drawing context.");*/ } if ( dc.context ) { @@ -243,6 +244,8 @@ XCopyArea( CGRectMake(src_x, src_y, width, height), CGRectMake(dest_x, dest_y, width, height)); CFRelease(img); + + } else { TkMacOSXDbgMsg("Failed to construct CGImage."); } @@ -652,9 +655,9 @@ GetCGContextForDrawable( CGColorSpaceRef colorspace = NULL; CGBitmapInfo bitmapInfo = #ifdef __LITTLE_ENDIAN__ - kCGBitmapByteOrder32Host; + kCGBitmapByteOrder32Host; #else - kCGBitmapByteOrderDefault; + kCGBitmapByteOrderDefault; #endif char *data; CGRect bounds = CGRectMake(0, 0, macDraw->size.width, @@ -731,6 +734,7 @@ DrawCGImage( } } dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff); + if (CGImageIsMask(image)) { /*CGContextSaveGState(context);*/ if (macDraw->flags & TK_IS_BW_PIXMAP) { @@ -1474,51 +1478,94 @@ TkScrollWindow( TkRegion damageRgn) /* Region to accumulate damage in. */ { Drawable drawable = Tk_WindowId(tkwin); - MacDrawable *macDraw = (MacDrawable *) drawable; + MacDrawable *macDraw = (MacDrawable *) drawable; NSView *view = TkMacOSXDrawableView(macDraw); CGRect srcRect, dstRect; - HIShapeRef dmgRgn = NULL, extraRgn; + HIShapeRef dmgRgn = NULL, extraRgn = NULL; NSRect bounds, visRect, scrollSrc, scrollDst; - int result; - + int result = 0; + if ( view ) { /* Get the scroll area in NSView coordinates (origin at bottom left). */ bounds = [view bounds]; scrollSrc = NSMakeRect( - macDraw->xOff + x, + macDraw->xOff + x, bounds.size.height - height - (macDraw->yOff + y), width, height); scrollDst = NSOffsetRect(scrollSrc, dx, -dy); + /* Limit scrolling to the window content area. */ visRect = [view visibleRect]; scrollSrc = NSIntersectionRect(scrollSrc, visRect); scrollDst = NSIntersectionRect(scrollDst, visRect); - if ( !NSIsEmptyRect(scrollSrc) && !NSIsEmptyRect(scrollDst) ) { - + /* * Mark the difference between source and destination as damaged. - * This region is described in the Tk coordinate system. + * This region is described in NSView coordinates (y=0 at the bottom) + * and converted to Tk coordinates later. */ - - srcRect = CGRectMake(x, y, width, height); - dstRect = CGRectOffset(srcRect, dx, dy); + + srcRect = CGRectMake(x, y, width, height); + dstRect = CGRectOffset(srcRect, dx, dy); + + /* Expand the rectangles slightly to avoid degeneracies. */ + srcRect.origin.y -= 1; + srcRect.size.height += 2; + dstRect.origin.y += 1; + dstRect.size.height -= 2; + + /* Compute the damage. */ dmgRgn = HIShapeCreateMutableWithRect(&srcRect); extraRgn = HIShapeCreateWithRect(&dstRect); ChkErr(HIShapeDifference, dmgRgn, extraRgn, (HIMutableShapeRef) dmgRgn); - CFRelease(extraRgn); - + result = HIShapeIsEmpty(dmgRgn) ? 0 : 1; + + /* Convert to Tk coordinates. */ + TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn); + if (extraRgn) { + CFRelease(extraRgn); + } + /* Scroll the rectangle. */ [view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)]; + + /* Shift the Tk children which meet the source rectangle. */ + TkWindow *winPtr = (TkWindow *)tkwin; + TkWindow *childPtr; + CGRect childBounds; + for (childPtr = winPtr->childList; childPtr != NULL; childPtr = childPtr->nextPtr) { + if (Tk_IsMapped(childPtr) && !Tk_IsTopLevel(childPtr)) { + TkMacOSXWinCGBounds(childPtr, &childBounds); + if (CGRectIntersectsRect(srcRect, childBounds)) { + MacDrawable *macChild = childPtr->privatePtr; + if (macChild) { + macChild->yOff += dy; + macChild->xOff += dx; + childPtr->changes.y = macChild->yOff; + childPtr->changes.x = macChild->xOff; + } + } + } + } + + /* Queue up Expose events for the damage region. */ + int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE); + [view generateExposeEvents:dmgRgn childrenOnly:1]; + Tcl_SetServiceMode(oldMode); + + /* Belt and suspenders: make the AppKit request a redraw + when it gets control again. */ + [view setNeedsDisplay:YES]; } + } else { + dmgRgn = HIShapeCreateEmpty(); + TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn); } - - if ( dmgRgn == NULL ) { - dmgRgn = HIShapeCreateEmpty(); + + if (dmgRgn) { + CFRelease(dmgRgn); } - TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn); - result = HIShapeIsEmpty(dmgRgn) ? 0 : 1; - CFRelease(dmgRgn); return result; } @@ -1853,6 +1900,7 @@ TkpClipDrawableToRect( CFRelease(macDraw->drawRgn); macDraw->drawRgn = NULL; } + if (width >= 0 && height >= 0) { CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff, width, height); @@ -2000,7 +2048,7 @@ TkpDrawHighlightBorder ( * TkpDrawFrame -- * * This procedure draws the rectangular frame area. If the user - * has request themeing, it draws with a the background theme. + * has requested themeing, it draws with the background theme. * * Results: * None. @@ -2030,6 +2078,7 @@ TkpDrawFrame( border = themedBorder; } } + Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, highlightWidth, highlightWidth, Tk_Width(tkwin) - 2 * highlightWidth, |