Skip to content

Instantly share code, notes, and snippets.

@Shilo
Created September 15, 2011 04:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Shilo/1218553 to your computer and use it in GitHub Desktop.
Save Shilo/1218553 to your computer and use it in GitHub Desktop.
A simple overflow text extension for Sparrow.
//
// SHOverflowTextField.h
// Sparrow
//
// Created by Shilo White on 9/14/11.
// Copyright 2011 Shilocity Productions. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SPTextField.h"
@interface SHOverflowTextField : SPTextField {
SHOverflowTextField *mLinkedTextField;
}
@property (nonatomic, retain) SHOverflowTextField *linkedTextField;
+ (SHOverflowTextField *)overflowTextFieldWithWidth:(float)width height:(float)height text:(NSString *)text fontName:(NSString *)name fontSize:(float)size color:(uint)color;
+ (SHOverflowTextField *)overflowTextFieldWithWidth:(float)width height:(float)height text:(NSString *)text;
+ (SHOverflowTextField *)overflowTextFieldWithText:(NSString *)text;
+ (SHOverflowTextField *)overflowTextField;
@end
//
// SHOverflowTextField.m
// Sparrow
//
// Created by Shilo White on 9/14/11.
// Copyright 2011 Shilocity Productions. All rights reserved.
//
#import "SHOverflowTextField.h"
#import <CoreText/CoreText.h>
@interface SPTextField (RequiresRedraw)
@property (nonatomic, assign) BOOL requiresRedraw;
@property (nonatomic, readonly) SPQuad *hitArea;
@property (nonatomic, readonly) SPQuad *textArea;
@end
@implementation SPTextField (RequiresRedraw)
- (void)setRequiresRedraw:(BOOL)requiresRedraw {
mRequiresRedraw = requiresRedraw;
}
- (BOOL)requiresRedraw {
return mRequiresRedraw;
}
- (SPQuad *)hitArea {
return mHitArea;
}
- (SPQuad *)textArea {
return mTextArea;
}
@end
@implementation SHOverflowTextField
@synthesize linkedTextField = mLinkedTextField;
+ (SHOverflowTextField *)overflowTextFieldWithWidth:(float)width height:(float)height text:(NSString *)text fontName:(NSString *)name fontSize:(float)size color:(uint)color {
return [[[self alloc] initWithWidth:width height:height text:text fontName:name fontSize:size color:color] autorelease];
}
+ (SHOverflowTextField *)overflowTextFieldWithWidth:(float)width height:(float)height text:(NSString *)text {
return [[[self alloc] initWithWidth:width height:height text:text] autorelease];
}
+ (SHOverflowTextField *)overflowTextFieldWithText:(NSString *)text {
return [[[self alloc] initWithText:text] autorelease];
}
+ (SHOverflowTextField *)overflowTextField {
return [[[self alloc] initWithText:@""] autorelease];
}
- (SPDisplayObject *)createRenderedContents
{
float width = self.hitArea.width;
float height = self.hitArea.height;
float fontSize = self.fontSize == SP_NATIVE_FONT_SIZE ? SP_DEFAULT_FONT_SIZE : self.fontSize;
UILineBreakMode lbm = (mLinkedTextField)?UILineBreakModeWordWrap:UILineBreakModeTailTruncation;
CGSize textSize = [self.text sizeWithFont:[UIFont fontWithName:self.fontName size:fontSize]
constrainedToSize:CGSizeMake(width, height) lineBreakMode:lbm];
float xOffset = 0;
if (self.hAlign == SPHAlignCenter) xOffset = (width - textSize.width) / 2.0f;
else if (self.hAlign == SPHAlignRight) xOffset = width - textSize.width;
float yOffset = 0;
if (self.vAlign == SPVAlignCenter) yOffset = (height - textSize.height) / 2.0f;
else if (self.vAlign == SPVAlignBottom) yOffset = height - textSize.height;
self.textArea.x = xOffset;
self.textArea.y = yOffset;
self.textArea.width = textSize.width;
self.textArea.height = textSize.height;
SPTexture *texture = [[SPTexture alloc] initWithWidth:width height:height
scale:[SPStage contentScaleFactor]
colorSpace:SPColorSpaceAlpha
draw:^(CGContextRef context)
{
if (self.border)
{
CGContextSetGrayStrokeColor(context, 1.0f, 1.0f);
CGContextSetLineWidth(context, 1.0f);
CGContextStrokeRect(context, CGRectMake(0.5f, 0.5f, width-1, height-1));
}
CGContextSetGrayFillColor(context, 1.0f, 1.0f);
[self.text drawInRect:CGRectMake(0, yOffset, width, height)
withFont:[UIFont fontWithName:self.fontName size:fontSize]
lineBreakMode:lbm alignment:self.hAlign];
if (mLinkedTextField) {
//CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate((CTParagraphStyleSetting[1]){{.spec = kCTParagraphStyleSpecifierLineBreakMode, .valueSize = sizeof(CTLineBreakMode), .value = (const void*)&lbm}}, 1);
CTFontRef fontAttribute = CTFontCreateWithName((CFStringRef)self.fontName, self.fontSize, NULL);
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:(id)fontAttribute, (NSString *)kCTFontAttributeName, nil]; //(id)paragraphStyle, (NSString *)kCTParagraphStyleAttributeName, nil];
CFRelease(fontAttribute);
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:self.text attributes:attributes];
CGMutablePathRef framePath = CGPathCreateMutable();
CGPathAddRect(framePath, NULL, CGRectMake(0, yOffset, width, height));
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedText);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), framePath, NULL);
CGPathRelease(framePath);
CFRelease(framesetter);
int visibleLength = CTFrameGetVisibleStringRange(frame).length;
CFRelease(frame);
if (visibleLength<self.text.length) {
NSString *overflowString = [[attributedText string] substringFromIndex:MAX(visibleLength, 0)];
if (![overflowString isEqualToString:@""]) mLinkedTextField.text = overflowString;
}
[attributedText release];
}
}];
SPImage *image = [SPImage imageWithTexture:texture];
image.color = self.color;
[texture release];
return image;
}
- (void)setLinkedTextField:(SHOverflowTextField *)linkedTextField {
if (linkedTextField != mLinkedTextField) {
[mLinkedTextField autorelease];
mLinkedTextField = [linkedTextField retain];
self.requiresRedraw = YES;
}
}
- (void)dealloc {
[mLinkedTextField release];
[super dealloc];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment