aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GTMiPhone.xcodeproj/project.pbxproj30
-rwxr-xr-xiPhone/GTMFadeTruncatingLabel.h32
-rwxr-xr-xiPhone/GTMFadeTruncatingLabel.m115
-rw-r--r--iPhone/GTMFadeTruncatingLabelTest.m67
-rw-r--r--iPhone/TestData/GTMFadeTruncatingLabelTest1.pngbin0 -> 2788 bytes
-rw-r--r--iPhone/TestData/GTMFadeTruncatingLabelTest2.pngbin0 -> 1569 bytes
-rw-r--r--iPhone/TestData/GTMFadeTruncatingLabelTest3.pngbin0 -> 3289 bytes
-rw-r--r--iPhone/TestData/GTMFadeTruncatingLabelTest4.pngbin0 -> 1919 bytes
-rw-r--r--iPhone/TestData/GTMFadeTruncatingLabelTest5.pngbin0 -> 2665 bytes
9 files changed, 244 insertions, 0 deletions
diff --git a/GTMiPhone.xcodeproj/project.pbxproj b/GTMiPhone.xcodeproj/project.pbxproj
index a91a4a9..9a88a9b 100644
--- a/GTMiPhone.xcodeproj/project.pbxproj
+++ b/GTMiPhone.xcodeproj/project.pbxproj
@@ -107,6 +107,13 @@
8BFE15C80FB0F764001BE894 /* GTMABAddressBookTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BFE15C30FB0F764001BE894 /* GTMABAddressBookTest.m */; };
8BFE15C90FB0F764001BE894 /* phone.png in Resources */ = {isa = PBXBuildFile; fileRef = 8BFE15C50FB0F764001BE894 /* phone.png */; };
8BFFCD7811C1934900E45777 /* GTMNSObject+KeyValueObservingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B6C18730F3769D200E51E5D /* GTMNSObject+KeyValueObservingTest.m */; };
+ 9340CF9F140550CE0026DDC9 /* GTMFadeTruncatingLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9340CF9D140550CE0026DDC9 /* GTMFadeTruncatingLabel.m */; };
+ 9340CFA0140550CE0026DDC9 /* GTMFadeTruncatingLabelTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 9340CF9E140550CE0026DDC9 /* GTMFadeTruncatingLabelTest.m */; };
+ 9340CFA6140550E30026DDC9 /* GTMFadeTruncatingLabelTest1.png in Resources */ = {isa = PBXBuildFile; fileRef = 9340CFA1140550E30026DDC9 /* GTMFadeTruncatingLabelTest1.png */; };
+ 9340CFA7140550E30026DDC9 /* GTMFadeTruncatingLabelTest2.png in Resources */ = {isa = PBXBuildFile; fileRef = 9340CFA2140550E30026DDC9 /* GTMFadeTruncatingLabelTest2.png */; };
+ 9340CFA8140550E30026DDC9 /* GTMFadeTruncatingLabelTest3.png in Resources */ = {isa = PBXBuildFile; fileRef = 9340CFA3140550E30026DDC9 /* GTMFadeTruncatingLabelTest3.png */; };
+ 9340CFA9140550E30026DDC9 /* GTMFadeTruncatingLabelTest4.png in Resources */ = {isa = PBXBuildFile; fileRef = 9340CFA4140550E30026DDC9 /* GTMFadeTruncatingLabelTest4.png */; };
+ 9340CFAA140550E30026DDC9 /* GTMFadeTruncatingLabelTest5.png in Resources */ = {isa = PBXBuildFile; fileRef = 9340CFA5140550E30026DDC9 /* GTMFadeTruncatingLabelTest5.png */; };
F417115A0ECDFF0400B9B276 /* GTMLightweightProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = F41711580ECDFF0400B9B276 /* GTMLightweightProxy.m */; };
F417115B0ECDFF0400B9B276 /* GTMLightweightProxyTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F41711590ECDFF0400B9B276 /* GTMLightweightProxyTest.m */; };
F418AF990E7558EC004FB565 /* GTMExceptionalInlines.m in Sources */ = {isa = PBXBuildFile; fileRef = F418AF940E7558DC004FB565 /* GTMExceptionalInlines.m */; };
@@ -274,6 +281,14 @@
8BFE15C20FB0F764001BE894 /* GTMABAddressBook.strings */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; path = GTMABAddressBook.strings; sourceTree = "<group>"; };
8BFE15C30FB0F764001BE894 /* GTMABAddressBookTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMABAddressBookTest.m; sourceTree = "<group>"; };
8BFE15C50FB0F764001BE894 /* phone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = phone.png; sourceTree = "<group>"; };
+ 9340CF9C140550CE0026DDC9 /* GTMFadeTruncatingLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMFadeTruncatingLabel.h; sourceTree = "<group>"; };
+ 9340CF9D140550CE0026DDC9 /* GTMFadeTruncatingLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMFadeTruncatingLabel.m; sourceTree = "<group>"; };
+ 9340CF9E140550CE0026DDC9 /* GTMFadeTruncatingLabelTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMFadeTruncatingLabelTest.m; sourceTree = "<group>"; };
+ 9340CFA1140550E30026DDC9 /* GTMFadeTruncatingLabelTest1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = GTMFadeTruncatingLabelTest1.png; path = TestData/GTMFadeTruncatingLabelTest1.png; sourceTree = "<group>"; };
+ 9340CFA2140550E30026DDC9 /* GTMFadeTruncatingLabelTest2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = GTMFadeTruncatingLabelTest2.png; path = TestData/GTMFadeTruncatingLabelTest2.png; sourceTree = "<group>"; };
+ 9340CFA3140550E30026DDC9 /* GTMFadeTruncatingLabelTest3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = GTMFadeTruncatingLabelTest3.png; path = TestData/GTMFadeTruncatingLabelTest3.png; sourceTree = "<group>"; };
+ 9340CFA4140550E30026DDC9 /* GTMFadeTruncatingLabelTest4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = GTMFadeTruncatingLabelTest4.png; path = TestData/GTMFadeTruncatingLabelTest4.png; sourceTree = "<group>"; };
+ 9340CFA5140550E30026DDC9 /* GTMFadeTruncatingLabelTest5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = GTMFadeTruncatingLabelTest5.png; path = TestData/GTMFadeTruncatingLabelTest5.png; sourceTree = "<group>"; };
CAD23A741174AE7800EA94E5 /* DebugiPhone32.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugiPhone32.xcconfig; sourceTree = "<group>"; };
CAD23A751174AE7800EA94E5 /* DebugiPhone313.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugiPhone313.xcconfig; sourceTree = "<group>"; };
CAD23A761174AE7800EA94E5 /* ReleaseiPhone32.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseiPhone32.xcconfig; sourceTree = "<group>"; };
@@ -387,6 +402,11 @@
64D0F5CB0FD3E66A00506CC7 /* TestData */ = {
isa = PBXGroup;
children = (
+ 9340CFA1140550E30026DDC9 /* GTMFadeTruncatingLabelTest1.png */,
+ 9340CFA2140550E30026DDC9 /* GTMFadeTruncatingLabelTest2.png */,
+ 9340CFA3140550E30026DDC9 /* GTMFadeTruncatingLabelTest3.png */,
+ 9340CFA4140550E30026DDC9 /* GTMFadeTruncatingLabelTest4.png */,
+ 9340CFA5140550E30026DDC9 /* GTMFadeTruncatingLabelTest5.png */,
64D0F5CC0FD3E68400506CC7 /* GTMUIImage+Resize_100x100_to_60x40.png */,
64D0F5CD0FD3E68400506CC7 /* GTMUIImage+Resize_50x100.png */,
448D61B011AC1AAD0097ACBC /* GTMUIImage+Resize_50x100_flipped.png */,
@@ -414,6 +434,9 @@
8BA5F4060E75669000798036 /* iPhone */ = {
isa = PBXGroup;
children = (
+ 9340CF9C140550CE0026DDC9 /* GTMFadeTruncatingLabel.h */,
+ 9340CF9D140550CE0026DDC9 /* GTMFadeTruncatingLabel.m */,
+ 9340CF9E140550CE0026DDC9 /* GTMFadeTruncatingLabelTest.m */,
F4E3B3D60EB5EF2400CB713D /* GTMUIFont+LineHeight.h */,
F4E3B3D70EB5EF2400CB713D /* GTMUIFont+LineHeight.m */,
F4E3B3E10EB5EF9A00CB713D /* GTMUIFont+LineHeightTest.m */,
@@ -752,6 +775,11 @@
64D0F5ED0FD3E68400506CC7 /* GTMUIImage+Resize_100x100.png in Resources */,
64D0F5EE0FD3E68400506CC7 /* GTMUIImage+Resize_100x100_to_40x60.png in Resources */,
64D0F5EF0FD3E68400506CC7 /* GTMUIImage+Resize_100x100_to_50x50.png in Resources */,
+ 9340CFA6140550E30026DDC9 /* GTMFadeTruncatingLabelTest1.png in Resources */,
+ 9340CFA7140550E30026DDC9 /* GTMFadeTruncatingLabelTest2.png in Resources */,
+ 9340CFA8140550E30026DDC9 /* GTMFadeTruncatingLabelTest3.png in Resources */,
+ 9340CFA9140550E30026DDC9 /* GTMFadeTruncatingLabelTest4.png in Resources */,
+ 9340CFAA140550E30026DDC9 /* GTMFadeTruncatingLabelTest5.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -852,6 +880,8 @@
8B2908B211F8E7070064F50F /* GTMNSFileHandle+UniqueName.m in Sources */,
8B2908B311F8E7070064F50F /* GTMNSFileHandle+UniqueNameTest.m in Sources */,
F4746721129703600022C1FB /* GTMSenTestCaseTest.m in Sources */,
+ 9340CF9F140550CE0026DDC9 /* GTMFadeTruncatingLabel.m in Sources */,
+ 9340CFA0140550CE0026DDC9 /* GTMFadeTruncatingLabelTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/iPhone/GTMFadeTruncatingLabel.h b/iPhone/GTMFadeTruncatingLabel.h
new file mode 100755
index 0000000..5b768f0
--- /dev/null
+++ b/iPhone/GTMFadeTruncatingLabel.h
@@ -0,0 +1,32 @@
+//
+// GTMFadeTruncatingLabel.h
+//
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef enum {
+ GTMFadeTruncatingTail = 0x1,
+ GTMFadeTruncatingHead = 0x2,
+ GTMFadeTruncatingHeadAndTail = GTMFadeTruncatingHead | GTMFadeTruncatingTail
+} GTMFadeTruncatingMode;
+
+@interface GTMFadeTruncatingLabel : UILabel
+
+// Which side(s) to truncate.
+@property(nonatomic, assign) GTMFadeTruncatingMode truncateMode;
+
+@end
diff --git a/iPhone/GTMFadeTruncatingLabel.m b/iPhone/GTMFadeTruncatingLabel.m
new file mode 100755
index 0000000..619e7bb
--- /dev/null
+++ b/iPhone/GTMFadeTruncatingLabel.m
@@ -0,0 +1,115 @@
+//
+// GTMFadeTruncatingLabel.m
+//
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+#import "GTMFadeTruncatingLabel.h"
+
+@interface GTMFadeTruncatingLabel ()
+- (void)setup;
+- (UIImage*)getLinearGradient:(CGRect)rect;
+@end
+
+@implementation GTMFadeTruncatingLabel
+
+@synthesize truncateMode = truncateMode_;
+
+- (void)setup {
+ self.backgroundColor = [UIColor clearColor];
+ truncateMode_ = GTMFadeTruncatingTail;
+}
+
+- (id)initWithFrame:(CGRect)frame {
+ self = [super initWithFrame:frame];
+ if (self) {
+ [self setup];
+ }
+ return self;
+}
+
+- (void)awakeFromNib {
+ [self setup];
+}
+
+// Draw fade gradient mask if text is wider than rect.
+- (void)drawTextInRect:(CGRect)requestedRect {
+ CGContextRef context = UIGraphicsGetCurrentContext();
+ CGContextSaveGState(context);
+
+ CGSize size = [self.text sizeWithFont:self.font];
+ if (size.width > requestedRect.size.width) {
+ UIImage* image = [self getLinearGradient:requestedRect];
+ CGContextClipToMask(context, self.bounds, image.CGImage);
+ }
+
+ CGContextSetFillColorWithColor(context, self.textColor.CGColor);
+ [self.text drawInRect:requestedRect
+ withFont:self.font
+ lineBreakMode:UILineBreakModeClip
+ alignment:self.textAlignment];
+
+ CGContextRestoreGState(context);
+}
+
+// Create gradient opacity mask based on direction.
+- (UIImage*)getLinearGradient:(CGRect)rect {
+ // Create an opaque context.
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
+ CGContextRef context = CGBitmapContextCreate (NULL,
+ rect.size.width,
+ rect.size.height,
+ 8,
+ 4*rect.size.width,
+ colorSpace,
+ kCGImageAlphaNone);
+
+ // White background will mask opaque, black gradient will mask transparent.
+ CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
+ CGContextFillRect(context, rect);
+
+ // Create gradient from white to black.
+ CGFloat locs[2] = { 0.0f, 1.0f };
+ CGFloat components[4] = { 1.0f, 1.0f, 0.0f, 1.0f };
+ CGGradientRef gradient =
+ CGGradientCreateWithColorComponents(colorSpace, components, locs, 2);
+ CGColorSpaceRelease(colorSpace);
+
+ // Draw head and/or tail gradient.
+ CGFloat fadeWidth = MIN(rect.size.height * 2, floor(rect.size.width / 4));
+ CGFloat minX = CGRectGetMinX(rect);
+ CGFloat maxX = CGRectGetMaxX(rect);
+ if (self.truncateMode & GTMFadeTruncatingTail) {
+ CGFloat startX = maxX - fadeWidth;
+ CGPoint startPoint = CGPointMake(startX, CGRectGetMidY(rect));
+ CGPoint endPoint = CGPointMake(maxX, CGRectGetMidY(rect));
+ CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
+ }
+ if (self.truncateMode & GTMFadeTruncatingHead) {
+ CGFloat startX = minX + fadeWidth;
+ CGPoint startPoint = CGPointMake(startX, CGRectGetMidY(rect));
+ CGPoint endPoint = CGPointMake(minX, CGRectGetMidY(rect));
+ CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
+ }
+ CGGradientRelease(gradient);
+
+ // Clean up, return image.
+ CGImageRef ref = CGBitmapContextCreateImage(context);
+ UIImage* image = [UIImage imageWithCGImage:ref];
+ CGImageRelease(ref);
+ CGContextRelease(context);
+ return image;
+}
+
+@end
diff --git a/iPhone/GTMFadeTruncatingLabelTest.m b/iPhone/GTMFadeTruncatingLabelTest.m
new file mode 100644
index 0000000..052a32f
--- /dev/null
+++ b/iPhone/GTMFadeTruncatingLabelTest.m
@@ -0,0 +1,67 @@
+//
+// GTMFadeTruncatingLabelTest.m
+//
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+#import "GTMNSObject+UnitTesting.h"
+#import "GTMSenTestCase.h"
+#import "GTMFadeTruncatingLabel.h"
+
+@interface GTMFadeTruncatingLabelTest : GTMTestCase
+@end
+
+
+@implementation GTMFadeTruncatingLabelTest
+
+- (void)testFadeTruncatingLabelRight {
+ GTMFadeTruncatingLabel* label = [[[GTMFadeTruncatingLabel alloc]
+ initWithFrame:CGRectMake(0, 0, 200, 25)]
+ autorelease];
+ label.text = @"A very long string that won't fit";
+ GTMAssertObjectImageEqualToImageNamed(label,
+ @"GTMFadeTruncatingLabelTest1",
+ @"Mismatched image.");
+ label.text = @"A short string";
+ GTMAssertObjectImageEqualToImageNamed(label,
+ @"GTMFadeTruncatingLabelTest2",
+ @"Mismatched image.");
+
+ // Dark background, light text.
+ label.backgroundColor = [UIColor blackColor];
+ [label setTextColor:[UIColor whiteColor]];
+
+ label.text = @"A very long string that won't fit";
+ GTMAssertObjectImageEqualToImageNamed(label,
+ @"GTMFadeTruncatingLabelTest3",
+ @"Mismatched image.");
+ label.text = @"A short string";
+ GTMAssertObjectImageEqualToImageNamed(label,
+ @"GTMFadeTruncatingLabelTest4",
+ @"Mismatched image.");
+}
+
+- (void)testFadeTruncatingLabelLeftAndRight {
+ GTMFadeTruncatingLabel* label = [[[GTMFadeTruncatingLabel alloc]
+ initWithFrame:CGRectMake(0, 0, 200, 25)]
+ autorelease];
+ label.truncateMode = GTMFadeTruncatingHeadAndTail;
+
+ label.text = @"Fade on both left and right";
+ GTMAssertObjectImageEqualToImageNamed(label,
+ @"GTMFadeTruncatingLabelTest5",
+ @"Mismatched image.");
+}
+
+@end
diff --git a/iPhone/TestData/GTMFadeTruncatingLabelTest1.png b/iPhone/TestData/GTMFadeTruncatingLabelTest1.png
new file mode 100644
index 0000000..d5d7910
--- /dev/null
+++ b/iPhone/TestData/GTMFadeTruncatingLabelTest1.png
Binary files differ
diff --git a/iPhone/TestData/GTMFadeTruncatingLabelTest2.png b/iPhone/TestData/GTMFadeTruncatingLabelTest2.png
new file mode 100644
index 0000000..80d95fd
--- /dev/null
+++ b/iPhone/TestData/GTMFadeTruncatingLabelTest2.png
Binary files differ
diff --git a/iPhone/TestData/GTMFadeTruncatingLabelTest3.png b/iPhone/TestData/GTMFadeTruncatingLabelTest3.png
new file mode 100644
index 0000000..eba21b2
--- /dev/null
+++ b/iPhone/TestData/GTMFadeTruncatingLabelTest3.png
Binary files differ
diff --git a/iPhone/TestData/GTMFadeTruncatingLabelTest4.png b/iPhone/TestData/GTMFadeTruncatingLabelTest4.png
new file mode 100644
index 0000000..e9f59c8
--- /dev/null
+++ b/iPhone/TestData/GTMFadeTruncatingLabelTest4.png
Binary files differ
diff --git a/iPhone/TestData/GTMFadeTruncatingLabelTest5.png b/iPhone/TestData/GTMFadeTruncatingLabelTest5.png
new file mode 100644
index 0000000..ba378d2
--- /dev/null
+++ b/iPhone/TestData/GTMFadeTruncatingLabelTest5.png
Binary files differ