aboutsummaryrefslogtreecommitdiff
path: root/AppKit
diff options
context:
space:
mode:
authorGravatar thomasvl@gmail.com <thomasvl@gmail.com@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2008-07-09 21:19:26 +0000
committerGravatar thomasvl@gmail.com <thomasvl@gmail.com@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2008-07-09 21:19:26 +0000
commit6ddca07d6c48b0226550b6ff3e01a177b6afd6a5 (patch)
treeadbd23d96eacb322eb47a1c8c525bc4d2536dfc3 /AppKit
parent098f7782e376e818b131a8f9a8222056c63d51ee (diff)
- Added GTMSignalHandler for simple signal handling (via kqueue/runloop).
- Fixed up GTMIPhoneUnitTestDelegate to be pickier about which tests it runs - Added GTMNSString+URLArguments to GTMiPhone - Added GTMHTTPFetcher and GTMHTTPServer to GTMiPhone - Made sure that build would work with iPhone device attached, and that all tests run directly on the phone. - Added GTMValidatingContainers which are a set of mutable container classes that allow you to have a selector on a target that is called to verify that the objects being put into the container are valid. This can be controlled at compile time so that you don't take the performance hit in a release build. - Added GTMPath, which represents an existing absolute path on the file system. It also makes it very easy to contruct new paths in the file system as well as whole directory hierarchies. - Added GTMNSString+Replace for a common replacement need. - Added NSString+FindFolder for two commen helpers for building paths to common locations. - Added GTMLargeTypeWindow for doing display windows similar to Address Book Large Type display for phone numbers.
Diffstat (limited to 'AppKit')
-rw-r--r--AppKit/GTMLargeTypeWindow.h51
-rw-r--r--AppKit/GTMLargeTypeWindow.m276
-rw-r--r--AppKit/GTMLargeTypeWindowTest.m146
-rw-r--r--AppKit/TestData/GTMLargeTypeWindowImageTest.gtmUTState49
-rw-r--r--AppKit/TestData/GTMLargeTypeWindowLongTextTest.gtmUTState26
-rw-r--r--AppKit/TestData/GTMLargeTypeWindowMediumTextTest.gtmUTState26
-rw-r--r--AppKit/TestData/GTMLargeTypeWindowShortTextTest.gtmUTState26
7 files changed, 600 insertions, 0 deletions
diff --git a/AppKit/GTMLargeTypeWindow.h b/AppKit/GTMLargeTypeWindow.h
new file mode 100644
index 0000000..9bb6b85
--- /dev/null
+++ b/AppKit/GTMLargeTypeWindow.h
@@ -0,0 +1,51 @@
+//
+// GTMLargeTypeWindow.h
+//
+// Copyright 2008 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 <Cocoa/Cocoa.h>
+
+// GTMLargeTypeWindow displays a block of text in a large panel window much
+// like Address Book displays phone numbers. It will also display an image
+// so you can pop up "alerts" similar to the way BBEdit does when you attempt
+// to do a find and find nothing. It will fade in and out appropriately when
+// ordered forward or backward.
+// A typical fire-and-forget type usage would be:
+// GTMLargeTypeWindow *window
+// = [[[GTMLargeTypeWindow alloc] initWithString:@"Foo"] autorelease];
+// [window makeKeyAndOrderFront:nil];
+
+// Amount of time to fade the window in or out
+const NSTimeInterval kGTMLargeTypeWindowFadeTime;
+
+@interface GTMLargeTypeWindow : NSPanel
+// Creates a display window with |string| displayed.
+// Formats |string| as best as possible to fill the screen.
+- (id)initWithString:(NSString *)string;
+// Creates a display window with |attrString| displayed.
+// Expects you to format it as you want it to appear.
+- (id)initWithAttributedString:(NSAttributedString *)attrString;
+// Creates a display window with |image| displayed.
+// Make sure you set the image size to what you want
+- (id)initWithImage:(NSImage*)image;
+// Creates a display window with |view| displayed.
+- (id)initWithContentView:(NSView *)view;
+
+// Copy the text out of the window if appropriate. This is normally called
+// as part of the responder chain so that the user can copy the displayed text
+// using cmd-c.
+- (void)copy:(id)sender;
+@end
diff --git a/AppKit/GTMLargeTypeWindow.m b/AppKit/GTMLargeTypeWindow.m
new file mode 100644
index 0000000..d84ce42
--- /dev/null
+++ b/AppKit/GTMLargeTypeWindow.m
@@ -0,0 +1,276 @@
+//
+// GTMLargeTypeWindow.m
+//
+// Copyright 2008 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 "GTMLargeTypeWindow.h"
+#import "GTMGeometryUtils.h"
+#import "GTMNSBezierPath+RoundRect.h"
+
+
+// Amount of time to fade the window in or out
+const NSTimeInterval kGTMLargeTypeWindowFadeTime = 0.333;
+
+// How far to inset the text from the edge of the window
+static const CGFloat kEdgeInset = 16.0;
+
+// Give us an alpha value for our backing window
+static const CGFloat kTwoThirdsAlpha = 0.66;
+
+@interface GTMLargeTypeBackgroundView : NSView
+@end
+
+@interface GTMLargeTypeWindow (GTMLargeTypeWindowPrivate)
++ (CGFloat)displayWidth;
+- (void)startFadeInAnimation;
+@end
+
+@implementation GTMLargeTypeWindow
+- (id)initWithString:(NSString *)string {
+ if ([string length] == 0) {
+ _GTMDevLog(@"GTMLargeTypeWindow got an empty string");
+ [self release];
+ return nil;
+ }
+ CGFloat displayWidth = [[self class] displayWidth];
+ NSMutableAttributedString *attrString
+ = [[[NSMutableAttributedString alloc] initWithString:string] autorelease];
+
+ // Try and find a size that fits without iterating too many times.
+ // We start going 50 pixels at a time, then 10, then 1
+ int size = -26; // start at 24 (-26 + 50)
+ int offsets[] = { 50, 10, 1 };
+ for (size_t i = 0; i < sizeof(offsets) / sizeof(int); ++i) {
+ for(size = size + offsets[i]; size >= 24 && size < 300; size += offsets[i]) {
+ NSFont *textFont = [NSFont boldSystemFontOfSize:size];
+ NSDictionary *fontAttr
+ = [NSDictionary dictionaryWithObject:textFont
+ forKey:NSFontAttributeName];
+ NSSize textSize = [string sizeWithAttributes:fontAttr];
+ if (textSize.width > displayWidth) {
+ size = size - offsets[i];
+ break;
+ }
+ }
+ }
+
+ // Bounds check our values
+ if (size > 300) {
+ size = 300;
+ } else if (size < 24) {
+ size = 24;
+ }
+
+ NSRange fullRange = NSMakeRange(0, [string length]);
+ [attrString addAttribute:NSFontAttributeName
+ value:[NSFont boldSystemFontOfSize:size]
+ range:fullRange];
+ [attrString addAttribute:NSForegroundColorAttributeName
+ value:[NSColor whiteColor]
+ range:fullRange];
+
+ NSMutableParagraphStyle *style
+ = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
+ [style setAlignment:NSCenterTextAlignment];
+ [attrString addAttribute:NSParagraphStyleAttributeName
+ value:style
+ range:fullRange];
+
+ NSShadow *textShadow = [[[NSShadow alloc] init] autorelease];
+ [textShadow setShadowOffset:NSMakeSize( 5, -5 )];
+ [textShadow setShadowBlurRadius:10];
+ [textShadow setShadowColor:[NSColor colorWithCalibratedWhite:0
+ alpha:kTwoThirdsAlpha]];
+ [attrString addAttribute:NSShadowAttributeName
+ value:textShadow
+ range:fullRange];
+ return [self initWithAttributedString:attrString];
+}
+
+- (id)initWithAttributedString:(NSAttributedString *)attrString {
+ if ([attrString length] == 0) {
+ _GTMDevLog(@"GTMLargeTypeWindow got an empty string");
+ [self release];
+ return nil;
+ }
+ CGFloat displayWidth =[[self class] displayWidth];
+ NSRect frame = NSMakeRect(0, 0, displayWidth, 0);
+ NSTextView *textView = [[[NSTextView alloc] initWithFrame:frame] autorelease];
+ [textView setEditable:NO];
+ [textView setSelectable:NO];
+ [textView setDrawsBackground:NO];
+ [[textView textStorage] setAttributedString:attrString];
+ [textView sizeToFit];
+
+ return [self initWithContentView:textView];
+}
+
+- (id)initWithImage:(NSImage*)image {
+ if (!image) {
+ _GTMDevLog(@"GTMLargeTypeWindow got an empty image");
+ [self release];
+ return nil;
+ }
+ NSRect rect = GTMNSRectOfSize([image size]);
+ NSImageView *imageView
+ = [[[NSImageView alloc] initWithFrame:rect] autorelease];
+ [imageView setImage:image];
+ return [self initWithContentView:imageView];
+}
+
+- (id)initWithContentView:(NSView *)view {
+ NSRect bounds = NSZeroRect;
+ if (view) {
+ bounds = [view bounds];
+ }
+ if (bounds.size.height <= 0 || bounds.size.width <= 0) {
+ _GTMDevLog(@"GTMLargeTypeWindow got an empty view");
+ [self release];
+ return nil;
+ }
+ NSRect screenRect = [[NSScreen mainScreen] frame];
+ NSRect windowRect = GTMNSAlignRectangles([view frame],
+ screenRect,
+ GTMRectAlignCenter);
+ windowRect = NSInsetRect(windowRect, -kEdgeInset, -kEdgeInset);
+ windowRect = NSIntegralRect(windowRect);
+ NSUInteger mask = NSBorderlessWindowMask | NSNonactivatingPanelMask;
+ self = [super initWithContentRect:windowRect
+ styleMask:mask
+ backing:NSBackingStoreBuffered
+ defer:NO];
+ if (self) {
+ [self setFrame:GTMNSAlignRectangles(windowRect,
+ screenRect,
+ GTMRectAlignCenter)
+ display:YES];
+ [self setBackgroundColor:[NSColor clearColor]];
+ [self setOpaque:NO];
+ [self setLevel:NSFloatingWindowLevel];
+ [self setHidesOnDeactivate:NO];
+
+ GTMLargeTypeBackgroundView *content
+ = [[[GTMLargeTypeBackgroundView alloc] initWithFrame:NSZeroRect]
+ autorelease];
+ [self setHasShadow:YES];
+ [self setContentView:content];
+ [self setAlphaValue:0];
+ [self setIgnoresMouseEvents:YES];
+ [view setFrame:GTMNSAlignRectangles([view frame],
+ [content frame],
+ GTMRectAlignCenter)];
+ [content addSubview:view];
+ [self setInitialFirstResponder:view];
+ }
+ return self;
+}
+
+- (void)copy:(id)sender {
+ id firstResponder = [self initialFirstResponder];
+ if ([firstResponder respondsToSelector:@selector(textStorage)]) {
+ NSPasteboard *pb = [NSPasteboard generalPasteboard];
+ [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self];
+ [pb setString:[[firstResponder textStorage] string]
+ forType:NSStringPboardType];
+ }
+}
+
+- (BOOL)canBecomeKeyWindow {
+ return YES;
+}
+
+- (void)keyDown:(NSEvent *)theEvent {
+ [self close];
+}
+
+- (void)resignKeyWindow {
+ [super resignKeyWindow];
+ if([self isVisible]) {
+ [self close];
+ }
+}
+
+- (void)makeKeyAndOrderFront:(id)sender {
+ [self startFadeInAnimation];
+ [super makeKeyAndOrderFront:sender];
+}
+
+- (void)orderFront:(id)sender {
+ [self startFadeInAnimation];
+ [super orderFront:sender];
+}
+
+- (void)orderOut:(id)sender {
+ NSDictionary *fadeOut = [NSDictionary dictionaryWithObjectsAndKeys:
+ self, NSViewAnimationTargetKey,
+ NSViewAnimationFadeOutEffect, NSViewAnimationEffectKey,
+ nil];
+ NSArray *animation = [NSArray arrayWithObject:fadeOut];
+ NSViewAnimation *viewAnim
+ = [[[NSViewAnimation alloc] initWithViewAnimations:animation] autorelease];
+ [viewAnim setDuration:kGTMLargeTypeWindowFadeTime];
+ [viewAnim startAnimation];
+ NSDate *fadeOutDate
+ = [NSDate dateWithTimeIntervalSinceNow:kGTMLargeTypeWindowFadeTime];
+ // We have a local run loop because if this is called as part of a close
+ // our window will be hidden immediately before it has a chance to fade.
+ [[NSRunLoop currentRunLoop] runUntilDate:fadeOutDate];
+}
+
++ (CGFloat)displayWidth {
+ NSRect screenRect = [[NSScreen mainScreen] frame];
+ // This is just a rough calculation to make us fill a good proportion
+ // of the main screen.
+ return NSWidth( screenRect ) * 11.0 / 12.0 - 2.0 * kEdgeInset;
+}
+
+- (void)startFadeInAnimation {
+ // If we aren't already fully visible, start fading us in.
+ if ([self alphaValue] < 1.0) {
+ NSDictionary *fadeIn = [NSDictionary dictionaryWithObjectsAndKeys:
+ self, NSViewAnimationTargetKey,
+ NSViewAnimationFadeInEffect, NSViewAnimationEffectKey,
+ nil];
+ NSArray *animation = [NSArray arrayWithObject:fadeIn];
+ NSViewAnimation *viewAnim
+ = [[[NSViewAnimation alloc] initWithViewAnimations:animation] autorelease];
+ [viewAnim setDuration:kGTMLargeTypeWindowFadeTime];
+ [viewAnim startAnimation];
+ }
+}
+@end
+
+@implementation GTMLargeTypeBackgroundView
+
+- (BOOL)isOpaque {
+ return NO;
+}
+
+- (void)drawRect:(NSRect)rect {
+ [[NSColor colorWithDeviceWhite:0 alpha:kTwoThirdsAlpha] set];
+ rect = [self bounds];
+
+ NSBezierPath *roundRect = [NSBezierPath bezierPath];
+ CGFloat minRadius = MIN(NSWidth(rect), NSHeight(rect)) * 0.5f;
+
+ [roundRect gtm_appendBezierPathWithRoundRect:rect
+ cornerRadius:MIN(minRadius, 32)];
+ [roundRect addClip];
+ NSRectFill(rect);
+ [super drawRect:rect];
+}
+
+@end
diff --git a/AppKit/GTMLargeTypeWindowTest.m b/AppKit/GTMLargeTypeWindowTest.m
new file mode 100644
index 0000000..b4a9fe4
--- /dev/null
+++ b/AppKit/GTMLargeTypeWindowTest.m
@@ -0,0 +1,146 @@
+//
+// GTMLargeTypeWindowTest.m
+//
+// Copyright 2006-2008 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 "GTMSenTestCase.h"
+#import "GTMLargeTypeWindow.h"
+#import "GTMNSObject+UnitTesting.h"
+#import "GTMUnitTestDevLog.h"
+
+NSString *const kLongTextBlock =
+ @"`Twas brillig, and the slithy toves "
+ "Did gyre and gimble in the wabe: "
+ "all mimsy were the borogoves, "
+ "and the mome raths outgrabe. "
+ "Beware the Jabberwock, my son! "
+ "The jaws that bite, the claws that catch! "
+ "Beware the Jubjub bird, and shun "
+ "the frumious Bandersnatch! "
+ "He took his vorpal sword in hand: "
+ "long time the manxome foe he sought -- "
+ "so rested he by the Tumtum tree, "
+ "and stood awhile in thought. "
+ "And, as in uffish thought he stood, "
+ "the Jabberwock, with eyes of flame, "
+ "came whiffling through the tulgey wood, "
+ "and burbled as it came! "
+ "One, two! One, two! And through and through "
+ "the vorpal blade went snicker-snack! "
+ "He left it dead, and with its head "
+ "he went galumphing back. "
+ "And, has thou slain the Jabberwock? "
+ "Come to my arms, my beamish boy! "
+ "O frabjous day! Callooh! Callay! "
+ "He chortled in his joy.";
+
+NSString *const kMediumTextBlock = @"For the Snark was a Boojum, you see.";
+
+@interface GTMLargeTypeWindowTest : GTMTestCase
+@end
+
+@implementation GTMLargeTypeWindowTest
+- (void)testLargeTypeWindow {
+ [GTMUnitTestDevLog expectString:@"GTMLargeTypeWindow got an empty string"];
+ GTMLargeTypeWindow *window = [[[GTMLargeTypeWindow alloc]
+ initWithString:@""] autorelease];
+ STAssertNil(window, nil);
+
+ [GTMUnitTestDevLog expectString:@"GTMLargeTypeWindow got an empty string"];
+ window = [[[GTMLargeTypeWindow alloc] initWithString:nil] autorelease];
+ STAssertNil(window, nil);
+
+ [GTMUnitTestDevLog expectString:@"GTMLargeTypeWindow got an empty string"];
+ NSAttributedString *attrString = [[[NSAttributedString alloc]
+ initWithString:@""] autorelease];
+ window = [[[GTMLargeTypeWindow alloc]
+ initWithAttributedString:attrString] autorelease];
+ STAssertNil(window, nil);
+
+ [GTMUnitTestDevLog expectString:@"GTMLargeTypeWindow got an empty string"];
+ window = [[[GTMLargeTypeWindow alloc]
+ initWithAttributedString:nil] autorelease];
+ STAssertNil(window, nil);
+
+ [GTMUnitTestDevLog expectString:@"GTMLargeTypeWindow got an empty view"];
+ window = [[[GTMLargeTypeWindow alloc] initWithContentView:nil] autorelease];
+ STAssertNil(window, nil);
+
+ [GTMUnitTestDevLog expectString:@"GTMLargeTypeWindow got an empty image"];
+ window = [[[GTMLargeTypeWindow alloc] initWithImage:nil] autorelease];
+ STAssertNil(window, nil);
+
+ window = [[[GTMLargeTypeWindow alloc]
+ initWithString:kMediumTextBlock] autorelease];
+ STAssertNotNil(window, nil);
+ STAssertTrue([window canBecomeKeyWindow], nil);
+ [window makeKeyAndOrderFront:nil];
+ NSDate *endDate
+ = [NSDate dateWithTimeIntervalSinceNow:kGTMLargeTypeWindowFadeTime];
+ [[NSRunLoop currentRunLoop] runUntilDate:endDate];
+ GTMAssertObjectStateEqualToStateNamed(window,
+ @"GTMLargeTypeWindowMediumTextTest",
+ nil);
+ [window copy:nil];
+ NSPasteboard *pb = [NSPasteboard generalPasteboard];
+ NSString *pbString = [pb stringForType:NSStringPboardType];
+ STAssertEqualObjects(pbString, kMediumTextBlock, nil);
+ [window keyDown:nil];
+
+ window = [[[GTMLargeTypeWindow alloc] initWithString:@"Short"] autorelease];
+ STAssertNotNil(window, nil);
+ STAssertTrue([window canBecomeKeyWindow], nil);
+ [window makeKeyAndOrderFront:nil];
+ endDate = [NSDate dateWithTimeIntervalSinceNow:kGTMLargeTypeWindowFadeTime];
+ [[NSRunLoop currentRunLoop] runUntilDate:endDate];
+ GTMAssertObjectStateEqualToStateNamed(window,
+ @"GTMLargeTypeWindowShortTextTest",
+ nil);
+ [window copy:nil];
+ pbString = [pb stringForType:NSStringPboardType];
+ STAssertEqualObjects(pbString, @"Short", nil);
+ [window resignKeyWindow];
+
+ window = [[[GTMLargeTypeWindow alloc]
+ initWithString:kLongTextBlock] autorelease];
+ STAssertNotNil(window, nil);
+ [window orderFront:nil];
+ endDate = [NSDate dateWithTimeIntervalSinceNow:kGTMLargeTypeWindowFadeTime];
+ [[NSRunLoop currentRunLoop] runUntilDate:endDate];
+ // Can't do state for long text as it will wrap differently on different
+ // sized screens.
+ GTMAssertObjectStateEqualToStateNamed(window,
+ @"GTMLargeTypeWindowLongTextTest",
+ nil);
+ [window keyDown:nil];
+
+ NSImage *image = [NSApp applicationIconImage];
+ window = [[[GTMLargeTypeWindow alloc] initWithImage:image] autorelease];
+ STAssertNotNil(window, nil);
+ [window makeKeyAndOrderFront:nil];
+ endDate = [NSDate dateWithTimeIntervalSinceNow:kGTMLargeTypeWindowFadeTime];
+ [[NSRunLoop currentRunLoop] runUntilDate:endDate];
+ GTMAssertObjectStateEqualToStateNamed(window,
+ @"GTMLargeTypeWindowImageTest",
+ nil);
+ [window copy:nil];
+ // Pasteboard should not change for an image
+ pbString = [pb stringForType:NSStringPboardType];
+ STAssertEqualObjects(pbString, @"Short", nil);
+ [window resignKeyWindow];
+}
+
+@end
diff --git a/AppKit/TestData/GTMLargeTypeWindowImageTest.gtmUTState b/AppKit/TestData/GTMLargeTypeWindowImageTest.gtmUTState
new file mode 100644
index 0000000..7a7512c
--- /dev/null
+++ b/AppKit/TestData/GTMLargeTypeWindowImageTest.gtmUTState
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>$GTMArchive</key>
+ <string>GTMUnitTestingArchive</string>
+ <key>$GTMVersion</key>
+ <integer>1</integer>
+ <key>WindowContent</key>
+ <dict>
+ <key>ViewIsHidden</key>
+ <false/>
+ <key>ViewSubView 0</key>
+ <dict>
+ <key>ControlIsEnabled</key>
+ <true/>
+ <key>ControlSelectedCell</key>
+ <dict>
+ <key>CellState</key>
+ <integer>0</integer>
+ <key>CellTag</key>
+ <integer>-1</integer>
+ <key>CellValue</key>
+ <dict>
+ <key>ImageSize</key>
+ <string>{128, 128}</string>
+ </dict>
+ </dict>
+ <key>ControlTag</key>
+ <integer>0</integer>
+ <key>ControlType</key>
+ <string>NSImageView</string>
+ <key>ControlValue</key>
+ <dict>
+ <key>ImageSize</key>
+ <string>{128, 128}</string>
+ </dict>
+ <key>ViewIsHidden</key>
+ <false/>
+ </dict>
+ </dict>
+ <key>WindowIsMain</key>
+ <false/>
+ <key>WindowIsVisible</key>
+ <true/>
+ <key>WindowTitle</key>
+ <string></string>
+</dict>
+</plist>
diff --git a/AppKit/TestData/GTMLargeTypeWindowLongTextTest.gtmUTState b/AppKit/TestData/GTMLargeTypeWindowLongTextTest.gtmUTState
new file mode 100644
index 0000000..e4687f5
--- /dev/null
+++ b/AppKit/TestData/GTMLargeTypeWindowLongTextTest.gtmUTState
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>$GTMArchive</key>
+ <string>GTMUnitTestingArchive</string>
+ <key>$GTMVersion</key>
+ <integer>1</integer>
+ <key>WindowContent</key>
+ <dict>
+ <key>ViewIsHidden</key>
+ <false/>
+ <key>ViewSubView 0</key>
+ <dict>
+ <key>ViewIsHidden</key>
+ <false/>
+ </dict>
+ </dict>
+ <key>WindowIsMain</key>
+ <false/>
+ <key>WindowIsVisible</key>
+ <true/>
+ <key>WindowTitle</key>
+ <string></string>
+</dict>
+</plist>
diff --git a/AppKit/TestData/GTMLargeTypeWindowMediumTextTest.gtmUTState b/AppKit/TestData/GTMLargeTypeWindowMediumTextTest.gtmUTState
new file mode 100644
index 0000000..e4687f5
--- /dev/null
+++ b/AppKit/TestData/GTMLargeTypeWindowMediumTextTest.gtmUTState
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>$GTMArchive</key>
+ <string>GTMUnitTestingArchive</string>
+ <key>$GTMVersion</key>
+ <integer>1</integer>
+ <key>WindowContent</key>
+ <dict>
+ <key>ViewIsHidden</key>
+ <false/>
+ <key>ViewSubView 0</key>
+ <dict>
+ <key>ViewIsHidden</key>
+ <false/>
+ </dict>
+ </dict>
+ <key>WindowIsMain</key>
+ <false/>
+ <key>WindowIsVisible</key>
+ <true/>
+ <key>WindowTitle</key>
+ <string></string>
+</dict>
+</plist>
diff --git a/AppKit/TestData/GTMLargeTypeWindowShortTextTest.gtmUTState b/AppKit/TestData/GTMLargeTypeWindowShortTextTest.gtmUTState
new file mode 100644
index 0000000..e4687f5
--- /dev/null
+++ b/AppKit/TestData/GTMLargeTypeWindowShortTextTest.gtmUTState
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>$GTMArchive</key>
+ <string>GTMUnitTestingArchive</string>
+ <key>$GTMVersion</key>
+ <integer>1</integer>
+ <key>WindowContent</key>
+ <dict>
+ <key>ViewIsHidden</key>
+ <false/>
+ <key>ViewSubView 0</key>
+ <dict>
+ <key>ViewIsHidden</key>
+ <false/>
+ </dict>
+ </dict>
+ <key>WindowIsMain</key>
+ <false/>
+ <key>WindowIsVisible</key>
+ <true/>
+ <key>WindowTitle</key>
+ <string></string>
+</dict>
+</plist>