From f736aed5642b3c7f19533653e1ddfd4599f1ee7d Mon Sep 17 00:00:00 2001 From: "gtm.daemon" Date: Tue, 9 Mar 2010 20:36:55 +0000 Subject: [Author: thomasvl] Add an api for forcing a NSTextField to a fixed height but what ever width is needed. R=dmaclach DELTA=634 (631 added, 0 deleted, 3 changed) --- AppKit/GTMUILocalizerAndLayoutTweaker.m | 77 +++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'AppKit/GTMUILocalizerAndLayoutTweaker.m') diff --git a/AppKit/GTMUILocalizerAndLayoutTweaker.m b/AppKit/GTMUILocalizerAndLayoutTweaker.m index 94bb637..6c1ae78 100644 --- a/AppKit/GTMUILocalizerAndLayoutTweaker.m +++ b/AppKit/GTMUILocalizerAndLayoutTweaker.m @@ -265,6 +265,83 @@ static BOOL IsRightAnchored(NSView *view); } } +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + ++ (CGFloat)sizeToFitFixedHeightTextField:(NSTextField *)textField { + return [self sizeToFitFixedHeightTextField:textField minWidth:(CGFloat)0]; +} + ++ (CGFloat)sizeToFitFixedHeightTextField:(NSTextField *)textField + minWidth:(NSUInteger)minWidth { + NSRect initialRect = [textField frame]; + NSCell *cell = [textField cell]; + NSSize titleSize = [cell titleRectForBounds:initialRect].size; + + // Find linebreak point, and keep trying them until we're under the height + // requested. + NSString *str = [textField stringValue]; + CFStringTokenizerRef tokenizer = + CFStringTokenizerCreate(NULL, + (CFStringRef)str, + CFRangeMake(0, [str length]), + kCFStringTokenizerUnitLineBreak, + NULL); + if (!tokenizer) { + _GTMDevAssert(tokenizer, @"failed to get a tokenizer"); + return 0.0; + } + NSCell *workerCell = [cell copy]; + NSCharacterSet *whiteSpaceSet = [NSCharacterSet whitespaceCharacterSet]; + + // Loop trying line break points until the height fits. + while (1) { + CFStringTokenizerTokenType tokenType = + CFStringTokenizerAdvanceToNextToken(tokenizer); + if (tokenType == kCFStringTokenizerTokenNone) { + // Reached the end without ever find a good width, how? + _GTMDevAssert(0, @"Failed to find a good size?!"); + [textField sizeToFit]; + break; + } + CFRange tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer); + + NSRange subStringRange = + NSMakeRange(0, tokenRange.location + tokenRange.length); + NSString *subString = [str substringWithRange:subStringRange]; + subString = [subString stringByTrimmingCharactersInSet:whiteSpaceSet]; + + // Find how wide the cell would be for this sub string. + [workerCell setStringValue:subString]; + CGFloat testWidth = [workerCell cellSize].width; + + // Find the overall size if wrapped to this width. + NSRect sizeRect = NSMakeRect(0, 0, testWidth, CGFLOAT_MAX); + NSSize newSize = [cell cellSizeForBounds:sizeRect]; + if (newSize.height <= titleSize.height) { + [textField setFrameSize:newSize]; + break; + } + } + + CFRelease(tokenizer); + + NSSize fixedSize = [textField frame].size; + NSSize finalSize = NSMakeSize(fixedSize.width, NSHeight(initialRect)); + + // Enforce the minWidth + if (minWidth > fixedSize.width) { + finalSize.width = minWidth; + } + if (!NSEqualSizes(fixedSize, finalSize)) { + [textField setFrameSize:finalSize]; + } + + // Return how much things changed + return NSWidth(initialRect) - finalSize.width; +} + +#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + + (void)resizeWindowWithoutAutoResizingSubViews:(NSWindow*)window delta:(NSSize)delta { NSView *contentView = [window contentView]; -- cgit v1.2.3