ARC: Update OakAppKit framework

This commit is contained in:
Allan Odgaard
2013-03-10 16:11:26 +01:00
parent 694b670413
commit 96784e9fee
41 changed files with 486 additions and 687 deletions

View File

@@ -18,7 +18,7 @@
+ (NSAlert*)tmAlertWithMessageText:(NSString*)messageText informativeText:(NSString*)informativeText buttons:(NSString*)firstTitle, ...
{
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
NSAlert* alert = [NSAlert new];
alert.messageText = messageText;
alert.informativeText = informativeText;

View File

@@ -21,7 +21,7 @@
{
if([self respondsToSelector:@selector(colorWithCGColor:)])
return [self colorWithCGColor:aColor];
return [NSColor colorWithColorSpace:[[[NSColorSpace alloc] initWithCGColorSpace:CGColorGetColorSpace(aColor)] autorelease] components:CGColorGetComponents(aColor) count:CGColorGetNumberOfComponents(aColor)];
return [NSColor colorWithColorSpace:[[NSColorSpace alloc] initWithCGColorSpace:CGColorGetColorSpace(aColor)] components:CGColorGetComponents(aColor) count:CGColorGetNumberOfComponents(aColor)];
}
- (CGColorRef)tmCGColor
@@ -35,6 +35,7 @@
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGColorRef res = CGColorCreate(colorSpace, rgba);
CGColorSpaceRelease(colorSpace);
return (CGColorRef)[(id)res autorelease];
__autoreleasing __attribute__ ((unused)) id dummy = CFBridgingRelease(res);
return res;
}
@end

View File

@@ -58,12 +58,6 @@
return copy;
}
- (void)dealloc
{
[contents release];
[super dealloc];
}
// NOTE: AppKit additions produce invalid values here, provide our own implementation
- (NSRect)boundingRectWithSize:(NSSize)aSize options:(NSStringDrawingOptions)options
@@ -77,20 +71,20 @@
{
CGSize stringSize = [string sizeWithAttributes:@{ NSFontAttributeName : font }];
NSTextTableBlock* block = [[[NSTextTableBlock alloc] initWithTable:table startingRow:row rowSpan:1 startingColumn:column columnSpan:1] autorelease];
NSTextTableBlock* block = [[NSTextTableBlock alloc] initWithTable:table startingRow:row rowSpan:1 startingColumn:column columnSpan:1];
if(column > 0)
[block setContentWidth:stringSize.width type:NSTextBlockAbsoluteValueType];
block.verticalAlignment = verticalAlignment;
NSMutableParagraphStyle* paragraphStyle = [[[NSMutableParagraphStyle alloc] init] autorelease];
NSMutableParagraphStyle* paragraphStyle = [NSMutableParagraphStyle new];
[paragraphStyle setTextBlocks:@[ block ]];
[paragraphStyle setAlignment:textAlignment];
string = [string stringByAppendingString:@"\n"];
NSMutableAttributedString* cellString = [[[NSMutableAttributedString alloc] initWithString:string] autorelease];
NSMutableAttributedString* cellString = [[NSMutableAttributedString alloc] initWithString:string];
[cellString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [cellString length])];
[cellString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [cellString length])];
@@ -162,8 +156,8 @@
if(aTabTrigger == NULL_STR)
return;
MenuMutableAttributedString* attributedTitle = [[[MenuMutableAttributedString alloc] init] autorelease];
NSTextTable* table = [[[NSTextTable alloc] init] autorelease];
MenuMutableAttributedString* attributedTitle = [MenuMutableAttributedString new];
NSTextTable* table = [NSTextTable new];
[table setNumberOfColumns:2];
NSFont* font = self.menu.font ?: [NSFont menuFontOfSize:0];

View File

@@ -13,7 +13,7 @@
{
if([self respondsToSelector:@selector(showsHiddenFiles)] && [self respondsToSelector:@selector(setShowsHiddenFiles:)])
{
NSViewController* viewController = [[[NSViewController alloc] initWithNibName:@"HiddenFilesAccessoryView" bundle:[NSBundle bundleWithIdentifier:@"com.macromates.TextMate.OakAppKit"]] autorelease];
NSViewController* viewController = [[NSViewController alloc] initWithNibName:@"HiddenFilesAccessoryView" bundle:[NSBundle bundleWithIdentifier:@"com.macromates.TextMate.OakAppKit"]];
[self setAccessoryView:viewController.view];
[self bind:@"showsHiddenFiles" toObject:[NSUserDefaultsController sharedUserDefaultsController] withKeyPath:@"values.NSOpenPanelShowHiddenFiles" options:nil];
}

View File

@@ -3,7 +3,7 @@
@implementation NSView (PopupAddition)
- (void)showMenu:(NSMenu*)menu inRect:(NSRect)rect withSelectedIndex:(NSInteger)index font:(NSFont*)font popup:(BOOL)isPopup
{
NSPopUpButtonCell* cell = [[[NSPopUpButtonCell alloc] init] autorelease];
NSPopUpButtonCell* cell = [NSPopUpButtonCell new];
[cell setPullsDown:!isPopup];
if(!isPopup)
[menu insertItemWithTitle:@"dummy title item" action:NULL keyEquivalent:@"" atIndex:0];

View File

@@ -3,10 +3,10 @@
NSString* const OakCursorDidHideNotification = @"OakCursorDidHideNotification";
@interface OakDividerLineView : NSBox
@property (nonatomic, retain) NSColor* primaryColor;
@property (nonatomic, retain) NSColor* secondaryColor;
@property (nonatomic) BOOL usePrimaryColor;
@property (nonatomic) NSSize intrinsicContentSize;
@property (nonatomic) NSColor* primaryColor;
@property (nonatomic) NSColor* secondaryColor;
@property (nonatomic) BOOL usePrimaryColor;
@property (nonatomic) NSSize intrinsicContentSize;
@end
@implementation OakDividerLineView
@@ -56,7 +56,7 @@ NSString* const OakCursorDidHideNotification = @"OakCursorDidHideNotification";
static OakDividerLineView* OakCreateDividerLineWithColor (NSColor* color, NSColor* secondaryColor)
{
OakDividerLineView* box = [[[OakDividerLineView alloc] initWithFrame:NSZeroRect] autorelease];
OakDividerLineView* box = [[OakDividerLineView alloc] initWithFrame:NSZeroRect];
box.boxType = NSBoxCustom;
box.borderType = NSLineBorder;
box.borderColor = color;
@@ -106,8 +106,8 @@ BOOL OakIsAlternateKeyOrMouseEvent (NSUInteger flags, NSEvent* anEvent)
}
@interface OakSheetCallbackDelegate : NSObject
@property (nonatomic, copy) void(^callback)(NSInteger);
@property (nonatomic, retain) id retainedSelf;
@property (nonatomic, copy) void(^callback)(NSInteger);
@property (nonatomic) id retainedSelf;
@end
@implementation OakSheetCallbackDelegate
@@ -126,23 +126,17 @@ BOOL OakIsAlternateKeyOrMouseEvent (NSUInteger flags, NSEvent* anEvent)
self.callback(returnCode);
self.retainedSelf = nil;
}
- (void)dealloc
{
self.callback = nil;
[super dealloc];
}
@end
void OakShowSheetForWindow (NSWindow* sheet, NSWindow* window, void(^callback)(NSInteger))
{
OakSheetCallbackDelegate* delegate = [[[OakSheetCallbackDelegate alloc] initWithBlock:callback] autorelease];
OakSheetCallbackDelegate* delegate = [[OakSheetCallbackDelegate alloc] initWithBlock:callback];
[NSApp beginSheet:sheet modalForWindow:window modalDelegate:delegate didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:NULL];
}
void OakShowAlertForWindow (NSAlert* alert, NSWindow* window, void(^callback)(NSInteger))
{
OakSheetCallbackDelegate* delegate = [[[OakSheetCallbackDelegate alloc] initWithBlock:callback] autorelease];
OakSheetCallbackDelegate* delegate = [[OakSheetCallbackDelegate alloc] initWithBlock:callback];
if(window)
[alert beginSheetModalForWindow:window modalDelegate:delegate didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:NULL];
else [delegate sheetDidEnd:alert returnCode:[alert runModal] contextInfo:NULL];

View File

@@ -4,27 +4,31 @@
#import <oak/oak.h>
// The lineBreakMode parameter is here to work around a crash in CoreText <rdar://6940427> — fixed in 10.6
static CFAttributedStringRef AttributedStringWithOptions (NSString* string, uint32_t options, NSLineBreakMode lineBreakMode = NSLineBreakByTruncatingTail)
static NSAttributedString* AttributedStringWithOptions (NSString* string, uint32_t options, NSLineBreakMode lineBreakMode = NSLineBreakByTruncatingTail)
{
NSMutableDictionary* attr = [NSMutableDictionary dictionary];
attr[NSFontAttributeName] = [NSFont controlContentFontOfSize:[NSFont smallSystemFontSize]];
NSMutableParagraphStyle* paragraph = [[NSMutableParagraphStyle new] autorelease];
NSMutableParagraphStyle* paragraph = [NSMutableParagraphStyle new];
[paragraph setLineBreakMode:lineBreakMode];
attr[NSParagraphStyleAttributeName] = paragraph;
NSAttributedString* res = [[[NSAttributedString alloc] initWithString:string attributes:attr] autorelease];
return (CFAttributedStringRef)res;
NSDictionary* attr = @{
NSParagraphStyleAttributeName : paragraph,
NSFontAttributeName : [NSFont controlContentFontOfSize:[NSFont smallSystemFontSize]]
};
return [[NSAttributedString alloc] initWithString:string attributes:attr];
}
double WidthOfText (NSString* string)
{
double width = 0;
CTLineRef line = CTLineCreateWithAttributedString(AttributedStringWithOptions(string, 0));
width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
CFRelease(line);
if(CFAttributedStringRef attrStr = (CFAttributedStringRef)CFBridgingRetain(AttributedStringWithOptions(string, 0)))
{
if(CTLineRef line = CTLineCreateWithAttributedString(attrStr))
{
width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
CFRelease(line);
}
CFRelease(attrStr);
}
return ceil(width);
}
@@ -38,7 +42,11 @@ static void DrawTextWithOptions (NSString* string, NSRect bounds, uint32_t textO
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, bounds);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(AttributedStringWithOptions(string, textOptions, bounds.size.width < 12 ? NSLineBreakByClipping : NSLineBreakByTruncatingTail));
CFAttributedStringRef attrStr = (CFAttributedStringRef)CFBridgingRetain(AttributedStringWithOptions(string, textOptions, bounds.size.width < 12 ? NSLineBreakByClipping : NSLineBreakByTruncatingTail));
if(!attrStr)
return;
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrStr);
CFRelease(attrStr);
if(!framesetter)
return;
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
@@ -265,9 +273,9 @@ OAK_DEBUG_VAR(OakControl);
while(candidate)
{
if([candidate respondsToSelector:action])
return (void)[candidate performSelector:action withObject:self];
return (void)[NSApp sendAction:action to:candidate from:self];
else if([candidate respondsToSelector:@selector(delegate)] && [[candidate performSelector:@selector(delegate)] respondsToSelector:action])
return (void)[[candidate performSelector:@selector(delegate)] performSelector:action withObject:self];
return (void)[NSApp sendAction:action to:[candidate performSelector:@selector(delegate)] from:self];
candidate = [candidate nextResponder];
}
}
@@ -409,12 +417,11 @@ struct rect_cmp_t
break;
}
}
if(!(trackingOptions & NSTrackingActiveAlways))
trackingOptions |= NSTrackingActiveInKeyWindow;
NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:it->first options:trackingOptions owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
[trackingArea release];
[self addTrackingArea:[[NSTrackingArea alloc] initWithRect:it->first options:trackingOptions owner:self userInfo:nil]];
}
}

View File

@@ -1,10 +1,5 @@
#import <oak/misc.h>
PUBLIC @interface OakEncodingPopUpButton : NSPopUpButton
{
NSArray* availableEncodings;
NSString* encoding;
NSMenuItem* firstMenuItem;
}
@property (nonatomic, retain) NSString* encoding;
@property (nonatomic) NSString* encoding;
@end

View File

@@ -81,7 +81,7 @@ namespace // PopulateMenu{Flat,Hierarchical}
{
groupName = item->group;
menu = [[NSMenu new] autorelease];
menu = [NSMenu new];
[menu setAutoenablesItems:NO];
[[containingMenu addItemWithTitle:[NSString stringWithCxxString:groupName] action:NULL keyEquivalent:@""] setSubmenu:menu];
}
@@ -103,12 +103,11 @@ namespace // PopulateMenu{Flat,Hierarchical}
@end
@interface OakEncodingPopUpButton ()
@property (nonatomic, retain) NSArray* availableEncodings;
@property (nonatomic) NSArray* availableEncodings;
@property (nonatomic) NSMenuItem* firstMenuItem;
@end
@implementation OakEncodingPopUpButton
@synthesize encoding, availableEncodings;
+ (void)initialize
{
NSArray* encodings = @[ @"WINDOWS-1252", @"MACROMAN", @"ISO-8859-1", @"UTF-8", @"UTF-16LE", @"UTF-16BE", @"SHIFT_JIS", @"GB18030" ];
@@ -121,8 +120,8 @@ namespace // PopulateMenu{Flat,Hierarchical}
for(NSString* str in [[NSUserDefaults standardUserDefaults] arrayForKey:kUserDefaultsAvailableEncodingsKey])
[encodings addObject:str];
if(encoding && ![encodings containsObject:encoding])
[encodings addObject:encoding];
if(self.encoding && ![encodings containsObject:self.encoding])
[encodings addObject:self.encoding];
self.availableEncodings = encodings;
}
@@ -130,33 +129,33 @@ namespace // PopulateMenu{Flat,Hierarchical}
- (void)updateMenu
{
std::vector<menu_item_t> items;
std::string currentEncodingsTitle = to_s(encoding);
std::string currentEncodingsTitle = to_s(self.encoding);
citerate(charset, encoding_list())
{
if([availableEncodings containsObject:[NSString stringWithCxxString:charset->code()]])
if([self.availableEncodings containsObject:[NSString stringWithCxxString:charset->code()]])
{
auto v = text::split(charset->name(), " ");
if(v.size() == 2)
{
items.push_back(menu_item_t(v.front(), v.back(), charset->code()));
if(to_s(encoding) == charset->code())
if(to_s(self.encoding) == charset->code())
currentEncodingsTitle = charset->name();
}
}
}
[self.menu removeAllItems];
firstMenuItem = nil;
self.firstMenuItem = nil;
if(items.size() >= 10)
{
firstMenuItem = [self.menu addItemWithTitle:[NSString stringWithCxxString:currentEncodingsTitle] action:NULL keyEquivalent:@""];
self.firstMenuItem = [self.menu addItemWithTitle:[NSString stringWithCxxString:currentEncodingsTitle] action:NULL keyEquivalent:@""];
[self.menu addItem:[NSMenuItem separatorItem]];
[self selectItem:firstMenuItem];
[self selectItem:self.firstMenuItem];
}
if(items.size() < 10)
[self selectItem:PopulateMenuFlat(self.menu, items, self, @selector(selectEncoding:), to_s(encoding))];
else PopulateMenuHierarchical(self.menu, items, self, @selector(selectEncoding:), to_s(encoding));
[self selectItem:PopulateMenuFlat(self.menu, items, self, @selector(selectEncoding:), to_s(self.encoding))];
else PopulateMenuHierarchical(self.menu, items, self, @selector(selectEncoding:), to_s(self.encoding));
[self.menu addItem:[NSMenuItem separatorItem]];
[[self.menu addItemWithTitle:@"Customize Encodings List…" action:@selector(customizeAvailableEncodings:) keyEquivalent:@""] setTarget:self];
@@ -166,7 +165,7 @@ namespace // PopulateMenu{Flat,Hierarchical}
{
if(self = [super initWithCoder:aCoder])
{
encoding = [@"UTF-8" retain];
self.encoding = @"UTF-8";
[self updateAvailableEncodings];
[self updateMenu];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDefaultsDidChange:) name:NSUserDefaultsDidChangeNotification object:[NSUserDefaults standardUserDefaults]];
@@ -178,7 +177,7 @@ namespace // PopulateMenu{Flat,Hierarchical}
{
if(self = [super initWithFrame:aRect pullsDown:flag])
{
encoding = [@"UTF-8" retain];
self.encoding = @"UTF-8";
[self updateAvailableEncodings];
[self updateMenu];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDefaultsDidChange:) name:NSUserDefaultsDidChangeNotification object:[NSUserDefaults standardUserDefaults]];
@@ -200,9 +199,6 @@ namespace // PopulateMenu{Flat,Hierarchical}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[encoding release];
[availableEncodings release];
[super dealloc];
}
- (void)selectEncoding:(NSMenuItem*)sender
@@ -212,23 +208,21 @@ namespace // PopulateMenu{Flat,Hierarchical}
- (void)setEncoding:(NSString*)newEncoding
{
if(encoding == newEncoding || [encoding isEqualToString:newEncoding])
if(_encoding == newEncoding || [_encoding isEqualToString:newEncoding])
return;
[encoding release];
encoding = [newEncoding retain];
if(encoding && ![availableEncodings containsObject:encoding])
_encoding = newEncoding;
if(_encoding && ![self.availableEncodings containsObject:_encoding])
[self updateAvailableEncodings];
[self updateMenu];
}
- (void)setAvailableEncodings:(NSArray*)newEncodings
{
if(availableEncodings == newEncodings || [availableEncodings isEqualToArray:newEncodings])
if(_availableEncodings == newEncodings || [_availableEncodings isEqualToArray:newEncodings])
return;
[availableEncodings release];
availableEncodings = [newEncodings retain];
_availableEncodings = newEncodings;
[self updateMenu];
}
@@ -248,21 +242,16 @@ namespace // PopulateMenu{Flat,Hierarchical}
// = Customize Encodings Window Controller =
// =========================================
static OakCustomizeEncodingsWindowController* SharedInstance;
@implementation OakCustomizeEncodingsWindowController
+ (OakCustomizeEncodingsWindowController*)sharedInstance
{
return SharedInstance ?: [[OakCustomizeEncodingsWindowController new] autorelease];
static OakCustomizeEncodingsWindowController* instance = [OakCustomizeEncodingsWindowController new];
return instance;
}
- (id)init
{
if(SharedInstance)
{
[self release];
}
else if(self = SharedInstance = [[super initWithWindowNibName:@"CustomizeEncodings"] retain])
if(self = [super initWithWindowNibName:@"CustomizeEncodings"])
{
std::set<std::string> enabledEncodings;
for(NSString* encoding in [[NSUserDefaults standardUserDefaults] arrayForKey:kUserDefaultsAvailableEncodingsKey])

View File

@@ -2,7 +2,7 @@
#import <scm/status.h>
PUBLIC @interface OakFileIconImage : NSImage
@property (nonatomic, retain) NSString* path;
@property (nonatomic) NSString* path;
@property (nonatomic) BOOL exists;
@property (nonatomic, getter = isDirectory) BOOL directory;
@property (nonatomic, getter = isAlias) BOOL alias;

View File

@@ -51,7 +51,7 @@ static NSImage* IconBadgeForAlias ()
IconRef iconRef;
if(GetIconRef(kOnSystemDisk, kSystemIconsCreator, kAliasBadgeIcon, &iconRef) == noErr)
{
NSImage* badge = [[[NSImage alloc] initWithIconRef:iconRef] autorelease];
NSImage* badge = [[NSImage alloc] initWithIconRef:iconRef];
ReleaseIconRef(iconRef);
return badge;
}
@@ -82,42 +82,35 @@ static NSImage* BadgeForSCMStatus (scm::status::type scmStatus)
// ===============================
@interface OakFileIconImageRep : NSImageRep
@property (nonatomic, retain) NSString* path;
@property (nonatomic) NSString* path;
@property (nonatomic) BOOL exists;
@property (nonatomic, getter = isDirectory) BOOL directory;
@property (nonatomic, getter = isAlias) BOOL alias;
@property (nonatomic) scm::status::type scmStatus;
@property (nonatomic, getter = isModified) BOOL modified;
@property (nonatomic, retain) NSArray* imageStack;
@property (nonatomic) NSArray* imageStack;
@end
@implementation OakFileIconImageRep
- (id)copyWithZone:(NSZone*)zone
{
OakFileIconImageRep* copy = [super copyWithZone:zone];
copy->_path = [_path retain];
copy->_path = _path;
copy->_exists = _exists;
copy->_directory = _directory;
copy->_alias = _alias;
copy->_scmStatus = _scmStatus;
copy->_modified = _modified;
copy->_imageStack = [_imageStack retain];
copy->_imageStack = _imageStack;
return copy;
}
- (void)dealloc
{
self.path = nil;
self.imageStack = nil;
[super dealloc];
}
- (NSArray*)imageStack
{
if(!_imageStack)
{
NSMutableArray* res = [NSMutableArray array];
_imageStack = [res retain];
_imageStack = res;
if(_path && _exists)
{
@@ -165,7 +158,7 @@ static NSImage* BadgeForSCMStatus (scm::status::type scmStatus)
NSImage* buffer = nil;
if(self.isModified)
{
buffer = [[[NSImage alloc] initWithSize:[self size]] autorelease];
buffer = [[NSImage alloc] initWithSize:[self size]];
[buffer lockFocus];
}
@@ -191,7 +184,7 @@ static NSImage* BadgeForSCMStatus (scm::status::type scmStatus)
// ====================
@interface OakFileIconImage ()
@property (nonatomic, retain) OakFileIconImageRep* fileIconImageRep;
@property (nonatomic) OakFileIconImageRep* fileIconImageRep;
@end
@implementation OakFileIconImage
@@ -241,16 +234,10 @@ static NSImage* BadgeForSCMStatus (scm::status::type scmStatus)
- (id)copyWithZone:(NSZone*)zone
{
OakFileIconImage* copy = [super copyWithZone:zone];
copy->_fileIconImageRep = [_fileIconImageRep retain];
copy->_fileIconImageRep = _fileIconImageRep;
return copy;
}
- (void)dealloc
{
self.fileIconImageRep = nil;
[super dealloc];
}
- (NSString*)path { return _fileIconImageRep.path; }
- (BOOL)exists { return _fileIconImageRep.exists; }
- (BOOL)isDirectory { return _fileIconImageRep.isDirectory; }
@@ -318,7 +305,7 @@ static NSImage* BadgeForSCMStatus (scm::status::type scmStatus)
}
}
+ (id)fileIconImageWithPath:(NSString*)aPath isModified:(BOOL)flag size:(NSSize)aSize { return [[[self alloc] initWithWithPath:aPath isModified:flag size:aSize] autorelease]; }
+ (id)fileIconImageWithPath:(NSString*)aPath isModified:(BOOL)flag size:(NSSize)aSize { return [[self alloc] initWithWithPath:aPath isModified:flag size:aSize]; }
+ (id)fileIconImageWithPath:(NSString*)aPath isModified:(BOOL)flag { return [self fileIconImageWithPath:aPath isModified:flag size:NSMakeSize(16, 16)]; }
+ (id)fileIconImageWithPath:(NSString*)aPath size:(NSSize)aSize { return [self fileIconImageWithPath:aPath isModified:NO size:aSize]; }
@end

View File

@@ -1,19 +1,8 @@
#import <oak/debug.h>
PUBLIC @interface OakFinderLabelChooser : NSView
{
OBJC_WATCH_LEAKS(OakFinderLabelChooser);
NSInteger selectedIndex;
NSInteger highlightedIndex;
NSMutableArray* labelNames;
BOOL enabled;
id target;
SEL action;
}
@property (nonatomic, assign) BOOL enabled;
@property (nonatomic, assign) id target;
@property (nonatomic, assign) SEL action;
@property (nonatomic, assign) NSInteger selectedIndex;
@property (nonatomic) BOOL enabled;
@property (nonatomic) NSInteger selectedIndex;
@property (nonatomic, weak) id target;
@property (nonatomic) SEL action;
@end

View File

@@ -5,13 +5,14 @@ static const CGFloat SwatchMargin = 4;
static const CGFloat LabelNameHeight = 15;
@interface OakFinderLabelChooser ()
@property (nonatomic, assign) NSInteger highlightedIndex;
{
OBJC_WATCH_LEAKS(OakFinderLabelChooser);
}
@property (nonatomic) NSMutableArray* labelNames;
@property (nonatomic) NSInteger highlightedIndex;
@end
@implementation OakFinderLabelChooser
@synthesize selectedIndex, highlightedIndex;
@synthesize enabled, target, action;
// ==================
// = Setup/Teardown =
// ==================
@@ -20,56 +21,48 @@ static const CGFloat LabelNameHeight = 15;
{
if(self = [super initWithFrame:rect])
{
enabled = YES;
highlightedIndex = -1;
self.enabled = YES;
self.highlightedIndex = -1;
}
return self;
}
- (void)dealloc
{
[labelNames release];
[super dealloc];
}
// =============
// = Accessors =
// =============
- (void)setSelectedIndex:(NSInteger)index
{
selectedIndex = index;
_selectedIndex = index;
[self setNeedsDisplay:YES];
}
- (void)setHighlightedIndex:(NSInteger)index
{
highlightedIndex = index;
_highlightedIndex = index;
[self setNeedsDisplay:YES];
}
- (NSArray*)labelNames
{
// GetLabel is deprecated and fails for non-MacRoman, but there is no replacement: <rdar://4772578>
if(!labelNames)
if(!_labelNames)
{
NSMutableDictionary* customLabels = [NSMutableDictionary dictionary];
for(NSString* path in [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSAllDomainsMask, YES) reverseObjectEnumerator])
{
path = [path stringByAppendingPathComponent:@"Preferences/com.apple.Labels.plist"];
if(NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile:path])
if(NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile:[path stringByAppendingPathComponent:@"Preferences/com.apple.Labels.plist"]])
[customLabels addEntriesFromDictionary:dict];
}
labelNames = [[NSMutableArray alloc] initWithObjects:@"None", @"Gray", @"Green", @"Purple", @"Blue", @"Yellow", @"Red", @"Orange", nil];
for(NSUInteger i = 1; i <= labelNames.count; ++i)
_labelNames = [[NSMutableArray alloc] initWithObjects:@"None", @"Gray", @"Green", @"Purple", @"Blue", @"Yellow", @"Red", @"Orange", nil];
for(NSUInteger i = 1; i <= self.labelNames.count; ++i)
{
if(NSString* label = [customLabels objectForKey:[NSString stringWithFormat:@"Label_Name_%lu", i]])
[labelNames replaceObjectAtIndex:i withObject:label];
[_labelNames replaceObjectAtIndex:i withObject:label];
}
}
return labelNames;
return _labelNames;
}
// ===========
@@ -78,8 +71,8 @@ static const CGFloat LabelNameHeight = 15;
- (NSRect)rectForSwatchAtIndex:(NSInteger)index
{
static const int LabelIndexMap[] = {0, 6, 7, 5, 2, 4, 3, 1};
index = std::distance(LabelIndexMap, std::find(&LabelIndexMap[0], &LabelIndexMap[0] + (sizeof(LabelIndexMap) / sizeof(LabelIndexMap[0])), index));
static int const LabelIndexMap[] = { 0, 6, 7, 5, 2, 4, 3, 1 };
index = std::distance(std::begin(LabelIndexMap), std::find(std::begin(LabelIndexMap), std::end(LabelIndexMap), index));
return (index < 8) ? NSMakeRect(22 + index*(SwatchDiameter + SwatchMargin*2), LabelNameHeight + 5, SwatchDiameter, SwatchDiameter) : NSZeroRect;
}
@@ -87,25 +80,25 @@ static const CGFloat LabelNameHeight = 15;
{
static struct swatch_t { struct { CGFloat red, green, blue; } from, to; } const swatches[] =
{
{{ 0, 0, 0}, { 0, 0, 0}},
{{ 205, 205, 206}, { 169, 169, 169}}, // Gray
{{ 212, 233, 151}, { 180, 214, 71}}, // Green
{{ 224, 190, 234}, { 192, 142, 217}}, // Purple
{{ 167, 208, 255}, { 90, 162, 255}}, // Blue
{{ 249, 242, 151}, { 239, 219, 71}}, // Yellow
{{ 252, 162, 154}, { 251, 100, 91}}, // Red
{{ 249, 206, 143}, { 246, 170, 68}}, // Orange
{ { 0, 0, 0}, { 0, 0, 0} },
{ { 205, 205, 206}, { 169, 169, 169} }, // Gray
{ { 212, 233, 151}, { 180, 214, 71} }, // Green
{ { 224, 190, 234}, { 192, 142, 217} }, // Purple
{ { 167, 208, 255}, { 90, 162, 255} }, // Blue
{ { 249, 242, 151}, { 239, 219, 71} }, // Yellow
{ { 252, 162, 154}, { 251, 100, 91} }, // Red
{ { 249, 206, 143}, { 246, 170, 68} }, // Orange
};
for(NSInteger i = 0; i < 8; i++)
for(NSInteger i = 0; i < 8; ++i)
{
NSRect swatchRect = [self rectForSwatchAtIndex:i];
if((i == highlightedIndex || (i == selectedIndex && selectedIndex != 0)) && enabled)
if((i == self.highlightedIndex || (i == self.selectedIndex && self.selectedIndex != 0)) && self.enabled)
{
NSRect outerRect = NSInsetRect(swatchRect, -SwatchMargin, -SwatchMargin);
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:outerRect xRadius:2 yRadius:2];
if(i == highlightedIndex)
NSBezierPath* path = [NSBezierPath bezierPathWithRoundedRect:outerRect xRadius:2 yRadius:2];
if(i == self.highlightedIndex)
{
[[NSColor colorWithCalibratedWhite:0.8 alpha:1] set];
[path fill];
@@ -118,11 +111,11 @@ static const CGFloat LabelNameHeight = 15;
{
[NSGraphicsContext saveGraphicsState];
if(enabled)
if(self.enabled)
{
NSShadow* shadow = [[[NSShadow alloc] init] autorelease];
NSShadow* shadow = [NSShadow new];
[shadow setShadowColor:[NSColor colorWithCalibratedWhite:0 alpha:0.75]];
[shadow setShadowOffset:NSMakeSize(0,-1)];
[shadow setShadowOffset:NSMakeSize(0, -1)];
[shadow setShadowBlurRadius:2];
[shadow set];
}
@@ -133,19 +126,19 @@ static const CGFloat LabelNameHeight = 15;
swatch_t const& swatch = swatches[i];
NSColor* startColor = [NSColor colorWithCalibratedRed:swatch.from.red/255.0 green:swatch.from.green/255.0 blue:swatch.from.blue/255.0 alpha:1];
NSColor* endColor = [NSColor colorWithCalibratedRed:swatch.to.red/255.0 green:swatch.to.green/255.0 blue:swatch.to.blue/255.0 alpha:1];
if(!enabled)
if(!self.enabled)
{
startColor = [startColor blendedColorWithFraction:0.3 ofColor:[NSColor grayColor]];
endColor = [startColor blendedColorWithFraction:0.5 ofColor:[NSColor grayColor]];
}
NSGradient *gradient = [[[NSGradient alloc] initWithStartingColor:startColor endingColor:endColor] autorelease];
NSGradient* gradient = [[NSGradient alloc] initWithStartingColor:startColor endingColor:endColor];
[gradient drawInRect:swatchRect angle:-90];
[NSGraphicsContext restoreGraphicsState];
}
else
{
if(enabled)
if(self.enabled)
[[NSColor colorWithCalibratedWhite:0.4 alpha:1] set];
else [[NSColor colorWithCalibratedWhite:0.7 alpha:1] set];
@@ -165,16 +158,16 @@ static const CGFloat LabelNameHeight = 15;
}
}
if(highlightedIndex != -1)
if(self.highlightedIndex != -1)
{
NSFont* font = [[NSFontManager sharedFontManager] convertFont:[NSFont menuFontOfSize:12] toHaveTrait:NSBoldFontMask];
NSString* name = [[self labelNames] objectAtIndex:highlightedIndex];
NSMutableParagraphStyle *style = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
NSMutableParagraphStyle* style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setAlignment:NSCenterTextAlignment];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName,
[NSColor grayColor], NSForegroundColorAttributeName,
style, NSParagraphStyleAttributeName,
nil];
NSDictionary* attributes = @{
NSFontAttributeName : [[NSFontManager sharedFontManager] convertFont:[NSFont menuFontOfSize:12] toHaveTrait:NSBoldFontMask],
NSForegroundColorAttributeName : [NSColor grayColor],
NSParagraphStyleAttributeName : style,
};
NSString* name = [[self labelNames] objectAtIndex:self.highlightedIndex];
[[NSString stringWithFormat:@"“%@”", name] drawInRect:NSMakeRect(0, 0, [self bounds].size.width, LabelNameHeight) withAttributes:attributes];
}
}
@@ -185,7 +178,7 @@ static const CGFloat LabelNameHeight = 15;
- (void)mouseDown:(NSEvent*)theEvent
{
if(!enabled)
if(!self.enabled)
return;
NSPoint localPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
@@ -214,10 +207,10 @@ static const CGFloat LabelNameHeight = 15;
for(NSInteger i = 0; i < 8; i++)
{
NSTrackingArea* trackingArea = [[[NSTrackingArea alloc] initWithRect:NSInsetRect([self rectForSwatchAtIndex:i], -SwatchMargin, -SwatchMargin)
options:NSTrackingMouseEnteredAndExited|NSTrackingActiveInKeyWindow
owner:self
userInfo:@{ @"index" : @(i) }] autorelease];
NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:NSInsetRect([self rectForSwatchAtIndex:i], -SwatchMargin, -SwatchMargin)
options:NSTrackingMouseEnteredAndExited|NSTrackingActiveInKeyWindow
owner:self
userInfo:@{ @"index" : @(i) }];
[self addTrackingArea:trackingArea];
}
}

View File

@@ -1,8 +1,8 @@
#import "OakGradientView.h"
@interface OakGradientView ()
@property (nonatomic, retain) NSGradient* activeGradient;
@property (nonatomic, retain) NSGradient* inactiveGradient;
@property (nonatomic) NSGradient* activeGradient;
@property (nonatomic) NSGradient* inactiveGradient;
@property (nonatomic) BOOL renderInactive;
@end
@@ -20,7 +20,6 @@
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (void)viewWillMoveToWindow:(NSWindow*)newWindow

View File

@@ -1,14 +1,9 @@
#import <oak/misc.h>
PUBLIC @interface OakImage : NSImage
{
NSImage* base;
NSImage* badge;
CGRectEdge edge;
}
@property (nonatomic, retain) NSImage* base;
@property (nonatomic, retain) NSImage* badge;
@property (nonatomic, assign) CGRectEdge edge;
@property (nonatomic) NSImage* base;
@property (nonatomic) NSImage* badge;
@property (nonatomic) CGRectEdge edge;
+ (OakImage*)imageWithBase:(NSImage*)imageBase;
+ (OakImage*)imageWithBase:(NSImage*)imageBase badge:(NSImage*)badgeImage;

View File

@@ -5,9 +5,7 @@
// ===============================
@interface OakCustomImageRep : NSImageRep
{
OakImage* image;
}
@property (nonatomic) OakImage* image;
- (id)initWithImage:(OakImage*)anImage;
@end
@@ -16,8 +14,8 @@
{
if((self = [super init]))
{
self.size = anImage.size;
image = anImage;
self.size = anImage.size;
self.image = anImage;
}
return self;
}
@@ -25,25 +23,20 @@
- (id)copyWithZone:(NSZone*)zone
{
OakCustomImageRep* copy = [super copyWithZone:zone];
copy->image = image;
copy.image = self.image;
return copy;
}
- (void)dealloc
{
[super dealloc];
}
- (BOOL)draw
{
NSSize imageSize = image.size;
NSSize badgeSize = image.badge.size;
NSSize imageSize = self.image.size;
NSSize badgeSize = self.image.badge.size;
CGFloat x = image.edge == CGRectMinXEdge || image.edge == CGRectMaxYEdge ? 0 : imageSize.width - badgeSize.width;
CGFloat y = image.edge == CGRectMinXEdge || image.edge == CGRectMinYEdge ? 0 : imageSize.height - badgeSize.height;
CGFloat x = self.image.edge == CGRectMinXEdge || self.image.edge == CGRectMaxYEdge ? 0 : imageSize.width - badgeSize.width;
CGFloat y = self.image.edge == CGRectMinXEdge || self.image.edge == CGRectMinYEdge ? 0 : imageSize.height - badgeSize.height;
[image.base drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:1];
[image.badge drawAtPoint:NSMakePoint(x, y) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
[self.image.base drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:1];
[self.image.badge drawAtPoint:NSMakePoint(x, y) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
return YES;
}
@end
@@ -53,8 +46,6 @@
// ============
@implementation OakImage
@synthesize base, badge, edge;
+ (OakImage*)imageWithBase:(NSImage*)imageBase
{
return [self imageWithBase:imageBase badge:nil edge:CGRectMinXEdge];
@@ -67,7 +58,7 @@
+ (OakImage*)imageWithBase:(NSImage*)imageBase badge:(NSImage*)badgeImage edge:(CGRectEdge)badgeEdge
{
OakImage* res = [[[self alloc] initWithSize:[imageBase size]] autorelease];
OakImage* res = [[self alloc] initWithSize:[imageBase size]];
res.base = imageBase;
res.badge = badgeImage;
res.edge = badgeEdge;
@@ -82,7 +73,7 @@
- (id)initWithSize:(NSSize)aSize
{
if((self = [super initWithSize:aSize]))
[self addRepresentation:[[[OakCustomImageRep alloc] initWithImage:self] autorelease]];
[self addRepresentation:[[OakCustomImageRep alloc] initWithImage:self]];
return self;
}
@@ -92,11 +83,4 @@
[imageRep setSize:aSize];
[super setSize:aSize];
}
- (void)dealloc
{
[base release];
[badge release];
[super dealloc];
}
@end

View File

@@ -6,10 +6,7 @@ enum {
};
PUBLIC @interface OakImageAndTextCell : NSTextFieldCell
{
NSImage* image;
}
@property (nonatomic, retain) NSImage* image;
@property (nonatomic) NSImage* image;
- (NSRect)imageFrameWithFrame:(NSRect)aRect inControlView:(NSView*)aView;
- (NSRect)textFrameWithFrame:(NSRect)aRect inControlView:(NSView*)aView;
@end

View File

@@ -2,18 +2,10 @@
#import "NSImage Additions.h"
@implementation OakImageAndTextCell
@synthesize image;
- (void)dealloc
{
[self setImage:nil];
[super dealloc];
}
- (id)copyWithZone:(NSZone*)zone
{
OakImageAndTextCell* cell = [super copyWithZone:zone];
cell->image = [image retain];
cell.image = self.image;
return cell;
}
@@ -49,13 +41,13 @@
- (NSRect)expansionFrameWithFrame:(NSRect)cellFrame inView:(NSView*)view
{
NSRect frame = [super expansionFrameWithFrame:[self textFrameWithFrame:cellFrame inControlView:view] inView:view];
frame.size.width -= image ? [image size].width + 3.0 : 0.0;
frame.size.width -= self.image ? [self.image size].width + 3.0 : 0.0;
return frame;
}
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView
{
if(image)
if(self.image)
{
NSRect imageRect = [self imageFrameWithFrame:cellFrame inControlView:controlView];
if([self drawsBackground])
@@ -63,7 +55,7 @@
[[self backgroundColor] set];
NSRectFill(imageRect);
}
[image drawAdjustedInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
[self.image drawAdjustedInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}
[super drawWithFrame:[self textFrameWithFrame:cellFrame inControlView:controlView] inView:controlView];
@@ -72,7 +64,7 @@
- (NSSize)cellSize
{
NSSize cellSize = [super cellSize];
cellSize.width += image ? [image size].width + 3.0 : 0.0;
cellSize.width += self.image ? [self.image size].width + 3.0 : 0.0;
return cellSize;
}

View File

@@ -2,19 +2,7 @@
#import <oak/misc.h>
PUBLIC @interface OakKeyEquivalentView : OakView
{
NSString* eventString;
NSString* displayString;
NSMutableArray* observers;
NSRect clearButtonRect;
void* hotkeyToken;
BOOL disableGlobalHotkeys;
BOOL showClearButton;
BOOL mouseInClearButton;
BOOL recording;
BOOL mouseDown;
}
@property (nonatomic, retain) NSString* eventString;
@property (nonatomic, assign) BOOL disableGlobalHotkeys;
@property (nonatomic, assign) BOOL recording;
@property (nonatomic) NSString* eventString;
@property (nonatomic) BOOL disableGlobalHotkeys;
@property (nonatomic) BOOL recording;
@end

View File

@@ -12,82 +12,78 @@ static NSString* const kBindingInfoKeyPathKey = @"keyPath";
static NSString* const kRecordingPlaceholderString = @"…";
@interface OakKeyEquivalentView ()
@property (nonatomic, retain) NSString* displayString;
@property (nonatomic, assign) BOOL showClearButton;
@property (nonatomic, assign) BOOL mouseInClearButton;
{
NSMutableArray* _observers;
NSRect _clearButtonRect;
void* _hotkeyToken;
BOOL _mouseDown;
}
@property (nonatomic) NSString* displayString;
@property (nonatomic) BOOL showClearButton;
@property (nonatomic) BOOL mouseInClearButton;
@end
@implementation OakKeyEquivalentView
@synthesize eventString, disableGlobalHotkeys, displayString, showClearButton, mouseInClearButton, recording;
- (id)initWithFrame:(NSRect)aRect
{
if(self = [super initWithFrame:aRect])
disableGlobalHotkeys = YES;
self.disableGlobalHotkeys = YES;
return self;
}
- (void)dealloc
{
for(NSDictionary* info in observers)
[[info objectForKey:kBindingInfoControllerKey] removeObserver:self forKeyPath:[info objectForKey:kBindingInfoKeyPathKey]];
[eventString release];
[displayString release];
[observers release];
[super dealloc];
for(NSDictionary* info in _observers)
[info[kBindingInfoControllerKey] removeObserver:self forKeyPath:info[kBindingInfoKeyPathKey]];
}
- (void)setEventString:(NSString*)aString
{
if(aString == eventString || [aString isEqualToString:eventString])
if(_eventString == aString || [_eventString isEqualToString:aString])
return;
[eventString release];
eventString = [aString retain];
self.showClearButton = NSNotEmptyString(eventString) && !recording;
self.displayString = recording ? kRecordingPlaceholderString : [NSString stringWithCxxString:ns::glyphs_for_event_string(to_s(eventString))];
_eventString = aString;
for(NSDictionary* info in observers)
self.showClearButton = NSNotEmptyString(self.eventString) && !self.recording;
self.displayString = self.recording ? kRecordingPlaceholderString : [NSString stringWithCxxString:ns::glyphs_for_event_string(to_s(_eventString))];
for(NSDictionary* info in _observers)
{
if([[info objectForKey:kBindingInfoBindingKey] isEqualToString:@"value"])
if([info[kBindingInfoBindingKey] isEqualToString:NSValueBinding])
{
id controller = [info objectForKey:kBindingInfoControllerKey];
NSString* keyPath = [info objectForKey:kBindingInfoKeyPathKey];
id controller = info[kBindingInfoControllerKey];
NSString* keyPath = info[kBindingInfoKeyPathKey];
NSString* oldValue = [controller valueForKeyPath:keyPath];
if(!oldValue || ![oldValue isEqualToString:eventString])
[controller setValue:eventString forKeyPath:keyPath];
if(!oldValue || ![oldValue isEqualToString:_eventString])
[controller setValue:_eventString forKeyPath:keyPath];
}
}
}
- (void)setDisplayString:(NSString*)aString
{
if(aString == displayString || [aString isEqualToString:displayString])
if(_displayString == aString || [_displayString isEqualToString:aString])
return;
[displayString release];
displayString = [aString retain];
_displayString = aString;
[self setNeedsDisplay:YES];
}
- (void)setShowClearButton:(BOOL)flag
{
if(flag == showClearButton)
if(_showClearButton == flag)
return;
showClearButton = flag;
if(flag)
if(_showClearButton = flag)
{
Class cl = NSClassFromString(@"OFBPathInfoCell");
NSImage* imgNormal = [NSImage imageNamed:@"CloseFile" inSameBundleAsClass:cl];
NSSize imgSize = imgNormal.size;
CGFloat imgMargin = floor((NSHeight([self bounds]) - imgSize.height) / 2);
clearButtonRect = NSMakeRect(NSWidth([self bounds]) - imgSize.width - imgMargin, imgMargin, imgSize.width, imgSize.height);
[self setNeedsDisplayInRect:clearButtonRect];
_clearButtonRect = NSMakeRect(NSWidth([self bounds]) - imgSize.width - imgMargin, imgMargin, imgSize.width, imgSize.height);
[self setNeedsDisplayInRect:_clearButtonRect];
NSTrackingArea* trackingArea = [[[NSTrackingArea alloc] initWithRect:clearButtonRect options:NSTrackingMouseEnteredAndExited|NSTrackingActiveAlways owner:self userInfo:nil] autorelease];
[self addTrackingArea:trackingArea];
[self addTrackingArea:[[NSTrackingArea alloc] initWithRect:_clearButtonRect options:NSTrackingMouseEnteredAndExited|NSTrackingActiveAlways owner:self userInfo:nil]];
}
else
{
@@ -95,34 +91,34 @@ static NSString* const kRecordingPlaceholderString = @"…";
[self removeTrackingArea:trackingArea];
self.mouseInClearButton = NO;
[self setNeedsDisplayInRect:clearButtonRect];
clearButtonRect = NSZeroRect;
[self setNeedsDisplayInRect:_clearButtonRect];
_clearButtonRect = NSZeroRect;
}
}
- (void)setRecording:(BOOL)flag
{
if(flag == recording)
if(_recording == flag)
return;
recording = flag;
self.showClearButton = NSNotEmptyString(eventString) && !recording;
self.displayString = recording ? kRecordingPlaceholderString : [NSString stringWithCxxString:ns::glyphs_for_event_string(to_s(eventString))];
_recording = flag;
self.showClearButton = NSNotEmptyString(self.eventString) && !self.recording;
self.displayString = _recording ? kRecordingPlaceholderString : [NSString stringWithCxxString:ns::glyphs_for_event_string(to_s(self.eventString))];
if(disableGlobalHotkeys)
if(self.disableGlobalHotkeys)
{
if(recording)
hotkeyToken = PushSymbolicHotKeyMode(kHIHotKeyModeAllDisabled);
else PopSymbolicHotKeyMode(hotkeyToken);
if(self.recording)
_hotkeyToken = PushSymbolicHotKeyMode(kHIHotKeyModeAllDisabled);
else PopSymbolicHotKeyMode(_hotkeyToken);
}
}
- (void)setMouseInClearButton:(BOOL)flag
{
if(flag == mouseInClearButton)
if(_mouseInClearButton == flag)
return;
mouseInClearButton = flag;
[self setNeedsDisplayInRect:clearButtonRect];
_mouseInClearButton = flag;
[self setNeedsDisplayInRect:_clearButtonRect];
}
- (void)setKeyState:(NSUInteger)newState
@@ -150,7 +146,7 @@ static NSString* const kRecordingPlaceholderString = @"…";
- (BOOL)isMouseDownInCloseButton:(NSEvent*)anEvent
{
return showClearButton && [anEvent type] == NSLeftMouseDown && NSMouseInRect([self convertPoint:[anEvent locationInWindow] fromView:nil], clearButtonRect, [self isFlipped]);
return self.showClearButton && [anEvent type] == NSLeftMouseDown && NSMouseInRect([self convertPoint:[anEvent locationInWindow] fromView:nil], _clearButtonRect, [self isFlipped]);
}
- (BOOL)acceptsFirstMouse:(NSEvent*)anEvent
@@ -174,23 +170,23 @@ static NSString* const kRecordingPlaceholderString = @"…";
{
[NSApp preventWindowOrdering];
mouseDown = YES;
[self setNeedsDisplayInRect:clearButtonRect];
_mouseDown = YES;
[self setNeedsDisplayInRect:_clearButtonRect];
while(true)
{
NSPoint mousePos = [self convertPoint:[anEvent locationInWindow] fromView:nil];
self.mouseInClearButton = NSMouseInRect(mousePos, clearButtonRect, [self isFlipped]);
self.mouseInClearButton = NSMouseInRect(mousePos, _clearButtonRect, [self isFlipped]);
if([anEvent type] == NSLeftMouseUp)
break;
anEvent = [NSApp nextEventMatchingMask:(NSLeftMouseUpMask|NSLeftMouseDraggedMask|NSRightMouseDownMask) untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:YES];
}
if(mouseInClearButton)
if(self.mouseInClearButton)
[self clearKeyEquivalent:self];
mouseDown = NO;
[self setNeedsDisplayInRect:clearButtonRect];
_mouseDown = NO;
[self setNeedsDisplayInRect:_clearButtonRect];
}
else
{
@@ -201,17 +197,17 @@ static NSString* const kRecordingPlaceholderString = @"…";
- (void)mouseEntered:(NSEvent*)anEvent
{
self.mouseInClearButton = NSMouseInRect([self convertPoint:[anEvent locationInWindow] fromView:nil], clearButtonRect, [self isFlipped]);
self.mouseInClearButton = NSMouseInRect([self convertPoint:[anEvent locationInWindow] fromView:nil], _clearButtonRect, [self isFlipped]);
}
- (void)mouseExited:(NSEvent*)anEvent
{
self.mouseInClearButton = NSMouseInRect([self convertPoint:[anEvent locationInWindow] fromView:nil], clearButtonRect, [self isFlipped]);
self.mouseInClearButton = NSMouseInRect([self convertPoint:[anEvent locationInWindow] fromView:nil], _clearButtonRect, [self isFlipped]);
}
- (void)flagsChanged:(NSEvent*)anEvent
{
if(recording)
if(self.recording)
{
std::string const str = ns::glyphs_for_flags([anEvent modifierFlags]);
self.displayString = str == "" ? kRecordingPlaceholderString : [NSString stringWithCxxString:str];
@@ -220,7 +216,7 @@ static NSString* const kRecordingPlaceholderString = @"…";
- (BOOL)performKeyEquivalent:(NSEvent*)anEvent
{
if(!recording)
if(!self.recording)
return NO;
self.eventString = [NSString stringWithCxxString:to_s(anEvent)];
@@ -230,7 +226,7 @@ static NSString* const kRecordingPlaceholderString = @"…";
- (void)keyDown:(NSEvent*)anEvent
{
if(recording)
if(self.recording)
{
[self performKeyEquivalent:anEvent];
}
@@ -269,21 +265,21 @@ static NSString* const kRecordingPlaceholderString = @"…";
NSEraseRect(NSIntersectionRect(aRect, NSInsetRect(frame, 1, 1)));
NSDictionary* stringAttributes = @{
NSForegroundColorAttributeName : recording ? [NSColor grayColor] : [NSColor blackColor],
NSForegroundColorAttributeName : self.recording ? [NSColor grayColor] : [NSColor blackColor],
NSFontAttributeName : [NSFont controlContentFontOfSize:0]
};
NSSize size = [displayString sizeWithAttributes:stringAttributes];
[displayString drawAtPoint:NSMakePoint(NSMidX([self visibleRect]) - size.width / 2, NSMidY([self visibleRect]) - size.height /2 ) withAttributes:stringAttributes];
NSSize size = [self.displayString sizeWithAttributes:stringAttributes];
[self.displayString drawAtPoint:NSMakePoint(NSMidX([self visibleRect]) - size.width / 2, NSMidY([self visibleRect]) - size.height /2 ) withAttributes:stringAttributes];
if(showClearButton)
if(self.showClearButton)
{
Class cl = NSClassFromString(@"OFBPathInfoCell");
NSImage* imgNormal = [NSImage imageNamed:@"CloseFile" inSameBundleAsClass:cl];
NSImage* imgHover = [NSImage imageNamed:@"CloseFileOver" inSameBundleAsClass:cl];
NSImage* imgDown = [NSImage imageNamed:@"CloseFilePressed" inSameBundleAsClass:cl];
NSImage* image = mouseInClearButton ? (mouseDown ? imgDown : imgHover) : imgNormal;
[image drawAdjustedInRect:clearButtonRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
NSImage* image = self.mouseInClearButton ? (_mouseDown ? imgDown : imgHover) : imgNormal;
[image drawAdjustedInRect:_clearButtonRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}
BOOL doesHaveFocus = (self.keyState & (OakViewViewIsFirstResponderMask|OakViewWindowIsKeyMask|OakViewApplicationIsActiveMask)) == (OakViewViewIsFirstResponderMask|OakViewWindowIsKeyMask|OakViewApplicationIsActiveMask);
@@ -302,36 +298,35 @@ static NSString* const kRecordingPlaceholderString = @"…";
- (void)bind:(NSString*)aBinding toObject:(id)observableController withKeyPath:(NSString*)aKeyPath options:(NSDictionary*)someOptions
{
observers = observers ?: [NSMutableArray new];
[observers addObject:[NSDictionary dictionaryWithObjectsAndKeys:
aBinding, kBindingInfoBindingKey,
observableController, kBindingInfoControllerKey,
aKeyPath, kBindingInfoKeyPathKey,
nil]];
_observers = _observers ?: [NSMutableArray new];
[_observers addObject:@{
kBindingInfoBindingKey : aBinding,
kBindingInfoControllerKey : observableController,
kBindingInfoKeyPathKey : aKeyPath,
}];
[observableController addObserver:self forKeyPath:aKeyPath options:NSKeyValueObservingOptionInitial context:NULL];
}
- (void)unbind:(NSString*)aBinding
{
for(NSUInteger i = [observers count]; i > 0; --i)
for(NSUInteger i = [_observers count]; i > 0; --i)
{
NSDictionary* info = [observers objectAtIndex:i-1];
if([aBinding isEqualToString:[info objectForKey:kBindingInfoBindingKey]])
NSDictionary* info = _observers[i-1];
if([aBinding isEqualToString:info[kBindingInfoBindingKey]])
{
[[info objectForKey:kBindingInfoControllerKey] removeObserver:self forKeyPath:[info objectForKey:kBindingInfoKeyPathKey]];
[observers removeObjectAtIndex:i-i];
[info[kBindingInfoControllerKey] removeObserver:self forKeyPath:info[kBindingInfoKeyPathKey]];
[_observers removeObjectAtIndex:i-i];
}
}
}
- (void)observeValueForKeyPath:(NSString*)aKeyPath ofObject:(id)observableController change:(NSDictionary*)changeDictionary context:(void*)userData
{
for(NSDictionary* info in observers)
for(NSDictionary* info in _observers)
{
if(observableController == [info objectForKey:kBindingInfoControllerKey] && [aKeyPath isEqualToString:[info objectForKey:kBindingInfoKeyPathKey]])
if(observableController == info[kBindingInfoControllerKey] && [aKeyPath isEqualToString:info[kBindingInfoKeyPathKey]])
{
if([[info objectForKey:kBindingInfoBindingKey] isEqualToString:@"value"])
if([info[kBindingInfoBindingKey] isEqualToString:NSValueBinding])
self.eventString = [observableController valueForKeyPath:aKeyPath];
}
}

View File

@@ -13,18 +13,20 @@ static std::vector< std::pair<NSString*, NSURL*> > ApplicationURLsForPaths (NSSe
for(NSString* path in paths)
{
NSURL* fileURL = [NSURL fileURLWithPath:path];
NSArray* applicationURLs = [(NSArray*)LSCopyApplicationURLsForURL((CFURLRef)fileURL, kLSRolesAll) autorelease];
NSURL* defaultApplicationURL = nil;
if(noErr == LSGetApplicationForURL((CFURLRef)fileURL, kLSRolesAll, NULL, (CFURLRef*)&defaultApplicationURL))
CFURLRef fileURL = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:path]);
NSArray* applicationURLs = (NSArray*)CFBridgingRelease(LSCopyApplicationURLsForURL(fileURL, kLSRolesAll));
CFURLRef defaultApplicationURL = nil;
if(noErr == LSGetApplicationForURL(fileURL, kLSRolesAll, NULL, &defaultApplicationURL))
{
if(![applicationURLs containsObject:defaultApplicationURL])
applicationURLs = [applicationURLs arrayByAddingObject:defaultApplicationURL];
[defaultApplicationURLs addObject:defaultApplicationURL];
NSURL* defaultAppURL = (NSURL*)CFBridgingRelease(defaultApplicationURL);
if(![applicationURLs containsObject:defaultAppURL])
applicationURLs = [applicationURLs arrayByAddingObject:defaultAppURL];
[defaultApplicationURLs addObject:defaultAppURL];
}
if(allApplicationURLs.count == 0)
[allApplicationURLs setSet:[NSSet setWithArray:applicationURLs]];
else [allApplicationURLs intersectSet:[NSSet setWithArray:applicationURLs]];
CFRelease(fileURL);
}
if(allApplicationURLs.count == 0)
@@ -59,26 +61,16 @@ static std::vector< std::pair<NSString*, NSURL*> > ApplicationURLsForPaths (NSSe
return res;
}
static OakOpenWithMenu* SharedInstance;
@implementation OakOpenWithMenu
+ (id)sharedInstance
{
return SharedInstance ?: [[self new] autorelease];
}
- (id)init
{
if(SharedInstance)
[self release];
else self = SharedInstance = [[super init] retain];
return SharedInstance;
static OakOpenWithMenu* instance = [OakOpenWithMenu new];
return instance;
}
+ (void)addOpenWithMenuForPaths:(NSSet*)paths toMenuItem:(NSMenuItem*)item
{
NSMenu* submenu = [[NSMenu new] autorelease];
[submenu setAutoenablesItems:NO];
NSMenu* submenu = [NSMenu new];
[submenu setDelegate:[OakOpenWithMenu sharedInstance]];
[item setRepresentedObject:paths];
@@ -95,7 +87,7 @@ static OakOpenWithMenu* SharedInstance;
if(appURLs.empty())
{
[[menu addItemWithTitle:@"No Suitable Applications Found" action:@selector(dummy:) keyEquivalent:@""] setEnabled:NO];
[menu addItemWithTitle:@"No Suitable Applications Found" action:@selector(nop:) keyEquivalent:@""];
return;
}
@@ -120,7 +112,7 @@ static OakOpenWithMenu* SharedInstance;
- (void)openWith:(id)sender
{
NSURL* applicationURL = [sender representedObject];
NSURL* applicationURL = [sender representedObject];
NSSet* filePaths = [[[sender menu] parentMenuItem] representedObject];
NSMutableArray* fileURLs = [NSMutableArray arrayWithCapacity:filePaths.count];

View File

@@ -12,44 +12,31 @@ extern PUBLIC NSString* const OakFindFullWordsOption;
extern PUBLIC NSString* const OakFindRegularExpressionOption;
PUBLIC @interface OakPasteboardEntry : NSObject
{
NSString* string;
NSMutableDictionary* options;
}
+ (OakPasteboardEntry*)pasteboardEntryWithString:(NSString*)aString;
+ (OakPasteboardEntry*)pasteboardEntryWithString:(NSString*)aString andOptions:(NSDictionary*)someOptions;
@property (nonatomic, copy) NSString* string;
@property (nonatomic, copy) NSDictionary* options;
@property (nonatomic, assign) BOOL fullWordMatch;
@property (nonatomic, assign) BOOL ignoreWhitespace;
@property (nonatomic, assign) BOOL regularExpression;
@property (nonatomic) BOOL fullWordMatch;
@property (nonatomic) BOOL ignoreWhitespace;
@property (nonatomic) BOOL regularExpression;
- (find::options_t)findOptions;
- (void)setFindOptions:(find::options_t)findOptions;
@end
PUBLIC @interface OakPasteboard : NSObject
{
@private
NSString* pasteboardName;
NSMutableArray* entries;
NSDictionary* auxiliaryOptionsForCurrent;
NSUInteger index;
NSInteger changeCount;
BOOL avoidsDuplicates;
}
+ (OakPasteboard*)pasteboardWithName:(NSString*)aName;
- (void)addEntry:(OakPasteboardEntry*)anEntry;
@property (nonatomic, assign) BOOL avoidsDuplicates;
@property (nonatomic) BOOL avoidsDuplicates;
- (OakPasteboardEntry*)previous;
- (OakPasteboardEntry*)current;
- (OakPasteboardEntry*)next;
@property (nonatomic, retain) NSDictionary* auxiliaryOptionsForCurrent;
@property (nonatomic) NSDictionary* auxiliaryOptionsForCurrent;
- (void)selectItemAtPosition:(NSPoint)aLocation andCall:(SEL)aSelector;
- (void)selectItemForControl:(NSView*)controlView;

View File

@@ -22,9 +22,13 @@ NSString* const OakFindRegularExpressionOption = @"regularExpression";
NSString* const kUserDefaultsDisablePersistentClipboardHistory = @"disablePersistentClipboardHistory";
@implementation OakPasteboardEntry
@synthesize string, options;
@interface OakPasteboardEntry ()
{
NSMutableDictionary* _options;
}
@end
@implementation OakPasteboardEntry
- (id)initWithString:(NSString*)aString andOptions:(NSDictionary*)someOptions
{
D(DBF_Pasteboard, bug("%s, %s\n", aString.UTF8String, someOptions.description.UTF8String););
@@ -32,21 +36,14 @@ NSString* const kUserDefaultsDisablePersistentClipboardHistory = @"disablePersis
if(self = [super init])
{
self.string = aString;
options = [[NSMutableDictionary alloc] initWithDictionary:someOptions];
self.options = [[NSMutableDictionary alloc] initWithDictionary:someOptions];
}
return self;
}
- (void)dealloc
{
[string release];
[options release];
[super dealloc];
}
+ (OakPasteboardEntry*)pasteboardEntryWithString:(NSString*)aString andOptions:(NSDictionary*)someOptions
{
return [[[self alloc] initWithString:aString andOptions:someOptions] autorelease];
return [[self alloc] initWithString:aString andOptions:someOptions];
}
+ (OakPasteboardEntry*)pasteboardEntryWithString:(NSString*)aString
@@ -56,32 +53,31 @@ NSString* const kUserDefaultsDisablePersistentClipboardHistory = @"disablePersis
- (void)setOptions:(NSDictionary*)aDictionary
{
if(options == aDictionary)
if(_options == aDictionary)
return;
[options release];
options = [[NSMutableDictionary dictionaryWithDictionary:aDictionary] retain];
_options = [NSMutableDictionary dictionaryWithDictionary:aDictionary];
}
- (BOOL)isEqual:(id)otherEntry
- (BOOL)isEqual:(OakPasteboardEntry*)otherEntry
{
return [otherEntry isKindOfClass:[self class]] && [string isEqual:[otherEntry string]];
return [otherEntry isKindOfClass:[self class]] && [self.string isEqual:otherEntry.string];
}
- (BOOL)fullWordMatch { return [[options objectForKey:OakFindFullWordsOption] boolValue]; };
- (BOOL)ignoreWhitespace { return [[options objectForKey:OakFindIgnoreWhitespaceOption] boolValue]; };
- (BOOL)regularExpression { return [[options objectForKey:OakFindRegularExpressionOption] boolValue]; };
- (BOOL)fullWordMatch { return [_options[OakFindFullWordsOption] boolValue]; };
- (BOOL)ignoreWhitespace { return [_options[OakFindIgnoreWhitespaceOption] boolValue]; };
- (BOOL)regularExpression { return [_options[OakFindRegularExpressionOption] boolValue]; };
- (void)setOption:(NSString*)aKey toBoolean:(BOOL)flag
{
if(!flag)
{
[options removeObjectForKey:aKey];
[_options removeObjectForKey:aKey];
return;
}
if(!options)
options = [[NSMutableDictionary alloc] init];
[options setObject:@YES forKey:aKey];
if(!_options)
_options = [NSMutableDictionary new];
_options[aKey] = @YES;
}
- (void)setFullWordMatch:(BOOL)flag { return [self setOption:OakFindFullWordsOption toBoolean:flag]; };
@@ -107,14 +103,21 @@ NSString* const kUserDefaultsDisablePersistentClipboardHistory = @"disablePersis
- (NSDictionary*)asDictionary
{
NSMutableDictionary* res = [NSMutableDictionary dictionaryWithDictionary:options];
if(string) // FIXME, how can this happen? Seems to happen when deleting preferences and exiting, likely bringing up the Find window first
[res setObject:string forKey:@"string"];
NSMutableDictionary* res = [NSMutableDictionary dictionaryWithDictionary:_options];
res[@"string"] = self.string ?: @"";
return res;
}
@end
@interface OakPasteboard (Private)
@interface OakPasteboard ()
{
NSString* pasteboardName;
NSMutableArray* entries;
NSDictionary* auxiliaryOptionsForCurrent;
NSUInteger index;
NSInteger changeCount;
BOOL avoidsDuplicates;
}
- (void)checkForExternalPasteboardChanges;
@end
@@ -242,7 +245,7 @@ namespace
{
if(self = [super init])
{
pasteboardName = [aName retain];
pasteboardName = aName;
entries = [NSMutableArray new];
if(![[[NSUserDefaults standardUserDefaults] objectForKey:kUserDefaultsDisablePersistentClipboardHistory] boolValue])
@@ -281,10 +284,6 @@ namespace
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidBecomeActiveNotification object:NSApp];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidResignActiveNotification object:NSApp];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillTerminateNotification object:NSApp];
[pasteboardName release];
[entries release];
[auxiliaryOptionsForCurrent release];
[super dealloc];
}
+ (OakPasteboard*)pasteboardWithName:(NSString*)aName
@@ -292,7 +291,7 @@ namespace
static NSMutableDictionary* SharedInstances = [NSMutableDictionary new];
if(![SharedInstances objectForKey:aName])
{
[SharedInstances setObject:[[[OakPasteboard alloc] initWithName:aName] autorelease] forKey:aName];
[SharedInstances setObject:[[OakPasteboard alloc] initWithName:aName] forKey:aName];
if(![aName isEqualToString:NSGeneralPboard])
[[SharedInstances objectForKey:aName] setAvoidsDuplicates:YES];
}
@@ -346,7 +345,6 @@ namespace
{
if(![newEntries isEqual:entries])
{
[entries release];
entries = [newEntries mutableCopy];
index = [entries count]-1;
self.auxiliaryOptionsForCurrent = nil;

View File

@@ -31,7 +31,7 @@ static size_t line_count (std::string const& text)
+ (id)cellWithMaxLines:(size_t)maxLines;
{
OakPasteboardSelectorMultiLineCell* cell = [[[self class] new] autorelease];
OakPasteboardSelectorMultiLineCell* cell = [[self class] new];
cell.maxLines = maxLines;
return cell;
}
@@ -65,7 +65,7 @@ static size_t line_count (std::string const& text)
NSAccessibilityRoleAttribute,
NSAccessibilityValueAttribute,
]];
attributes = [[set allObjects] retain];
attributes = [set allObjects];
}
return attributes;
}
@@ -99,8 +99,7 @@ static size_t line_count (std::string const& text)
{
NSString* moreLinesText = [NSString stringWithFormat:@"%lu more line%s", [lines count] - [clippedLines count], ([lines count] - [clippedLines count]) != 1 ? "s" : ""];
NSDictionary* moreLinesAttributes = @{ NSForegroundColorAttributeName : ([self isHighlighted] ? [NSColor darkGrayColor] : [NSColor lightGrayColor]) };
NSAttributedString* moreLines = [[[NSAttributedString alloc] initWithString:moreLinesText
attributes:moreLinesAttributes] autorelease];
NSAttributedString* moreLines = [[NSAttributedString alloc] initWithString:moreLinesText attributes:moreLinesAttributes];
NSSize size = [moreLines size];
NSRect moreLinesRect = rowFrame;
moreLinesRect.origin.x += frame.size.width - size.width;
@@ -146,8 +145,6 @@ static size_t line_count (std::string const& text)
- (void)dealloc
{
[self setTableView:nil];
[entries release];
[super dealloc];
}
- (NSInteger)numberOfRowsInTableView:(NSTableView*)aTableView
@@ -177,13 +174,10 @@ static size_t line_count (std::string const& text)
[tableView setTarget:nil];
[tableView setDataSource:nil];
[tableView setNextResponder:[self nextResponder]];
[tableView release];
}
if(aTableView)
if(tableView = aTableView)
{
tableView = [aTableView retain];
[tableView setDataSource:self];
[tableView setDelegate:self];
[tableView reloadData];
@@ -288,32 +282,21 @@ static size_t line_count (std::string const& text)
}
@end
static OakPasteboardSelector* SharedInstance;
@implementation OakPasteboardSelector
+ (OakPasteboardSelector*)sharedInstance
{
return SharedInstance ?: [[OakPasteboardSelector new] autorelease];
static OakPasteboardSelector* instance = [OakPasteboardSelector new];
return instance;
}
- (id)init
{
if(SharedInstance)
{
[self release];
}
else if(self = SharedInstance = [[super initWithWindowNibName:@"Pasteboard Selector"] retain])
if(self = [super initWithWindowNibName:@"Pasteboard Selector"])
{
[self setShouldCascadeWindows:NO];
[self window];
}
return SharedInstance;
}
- (void)dealloc
{
[tableViewHelper release];
[super dealloc];
return self;
}
- (void)setIndex:(unsigned)index
@@ -324,7 +307,6 @@ static OakPasteboardSelector* SharedInstance;
- (void)setEntries:(NSArray*)entries
{
[self setIndex:0];
[tableViewHelper release];
tableViewHelper = [[OakPasteboardSelectorTableViewHelper alloc] initWithEntries:entries];
[tableViewHelper setTableView:tableView];
}

View File

@@ -1,6 +1,7 @@
#import "OakPopOutAnimation.h"
#import "NSImage Additions.h"
#import <oak/algorithm.h>
#import <oak/debug.h>
static CGFloat const kExtendWidth = 6;
static CGFloat const kExtendHeight = 1;
@@ -11,15 +12,15 @@ static double const kFadeDuration = 0.60;
@interface OakPopOutView : NSView
{
NSRect baseFrame;
NSImage* contentImage;
NSDate* animationStartTime;
OBJC_WATCH_LEAKS(OakPopOutView);
NSRect baseFrame;
double growDuration;
double fadeDuration;
}
@property (nonatomic, retain) NSDate* animationStartTime;
@property (nonatomic, retain) NSImage* contentImage;
@property (nonatomic) NSDate* animationStartTime;
@property (nonatomic) NSImage* contentImage;
@property (nonatomic) NSWindow* retainedWindow;
- (void)startAnimation:(id)sender;
@end
@@ -38,9 +39,10 @@ void OakShowPopOutAnimation (NSRect aRect, NSImage* anImage)
[window setReleasedWhenClosed:NO];
[window useOptimizedDrawing:YES];
OakPopOutView* aView = [[[OakPopOutView alloc] initWithFrame:contentRect] autorelease];
OakPopOutView* aView = [[OakPopOutView alloc] initWithFrame:contentRect];
[aView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
aView.contentImage = anImage;
aView.retainedWindow = window;
[[window contentView] addSubview:aView];
[window setFrame:aRect display:YES];
@@ -56,8 +58,6 @@ static double bounce_curve (double t)
}
@implementation OakPopOutView
@synthesize animationStartTime, contentImage;
- (id)initWithFrame:(NSRect)aRect
{
if(self = [super initWithFrame:aRect])
@@ -69,16 +69,10 @@ static double bounce_curve (double t)
return self;
}
- (void)dealloc
{
[animationStartTime release];
[super dealloc];
}
- (void)startAnimation:(id)sender
{
baseFrame = [[self window] frame];
self.animationStartTime = [[NSDate date] retain];
self.animationStartTime = [NSDate date];
[NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(animationTick:) userInfo:nil repeats:YES];
}
@@ -89,12 +83,12 @@ static double bounce_curve (double t)
CGFloat alpha = 1.0;
CGFloat grow = 0.0;
double t = -[animationStartTime timeIntervalSinceNow];
double t = -[self.animationStartTime timeIntervalSinceNow];
if(t > totalDuration)
{
[aTimer invalidate];
[[self window] orderOut:self];
[[self window] release];
self.retainedWindow = nil;
return;
}
else if(t > 2*growDuration)
@@ -131,7 +125,7 @@ static double bounce_curve (double t)
[[NSColor whiteColor] set];
[roundedRect stroke];
[contentImage drawAdjustedInRect:NSInsetRect([self bounds], kExtendWidth, kExtendHeight) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
[self.contentImage drawAdjustedInRect:NSInsetRect([self bounds], kExtendWidth, kExtendHeight) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
[super drawRect:aRect];
}

View File

@@ -1,4 +1,4 @@
#include <file/encoding.h>
#import <file/encoding.h>
#import <oak/misc.h>
PUBLIC @interface OakSavePanel : NSObject

View File

@@ -9,18 +9,16 @@
{
IBOutlet OakEncodingPopUpButton* encodingPopUpButton;
encoding::type encodingOptions;
encoding::type _encodingOptions;
}
@property (nonatomic, retain) NSString* lineEndings;
@property (nonatomic, retain) NSString* encoding;
@property (nonatomic, assign) BOOL useByteOrderMark;
@property (nonatomic) NSString* lineEndings;
@property (nonatomic) NSString* encoding;
@property (nonatomic) BOOL useByteOrderMark;
@property (nonatomic, readonly) BOOL canUseByteOrderMark;
@property (nonatomic, readonly) encoding::type const& encodingOptions;
@end
@implementation OakEncodingSaveOptionsViewController
@synthesize encodingOptions;
+ (NSSet*)keyPathsForValuesAffectingCanUseByteOrderMark { return [NSSet setWithObject:@"encoding"]; }
+ (NSSet*)keyPathsForValuesAffectingUseByteOrderMark { return [NSSet setWithObject:@"encoding"]; }
@@ -33,14 +31,13 @@
- (id)initWithEncodingOptions:(encoding::type const&)someEncodingOptions
{
if(self = [super initWithNibName:@"EncodingSaveOptions" bundle:[NSBundle bundleForClass:[self class]]])
encodingOptions = someEncodingOptions;
_encodingOptions = someEncodingOptions;
return self;
}
- (void)dealloc
{
[self unbind:@"encoding"];
[super dealloc];
}
- (void)loadView
@@ -50,21 +47,21 @@
[self bind:@"encoding" toObject:encodingPopUpButton withKeyPath:@"encoding" options:nil];
}
- (BOOL)canUseByteOrderMark { return encodingOptions.supports_byte_order_mark(encodingOptions.charset()); }
- (BOOL)canUseByteOrderMark { return _encodingOptions.supports_byte_order_mark(_encodingOptions.charset()); }
- (NSString*)lineEndings { return [NSString stringWithCxxString:encodingOptions.newlines()]; }
- (NSString*)encoding { return [NSString stringWithCxxString:encodingOptions.charset()]; }
- (BOOL)useByteOrderMark { return encodingOptions.byte_order_mark(); }
- (NSString*)lineEndings { return [NSString stringWithCxxString:_encodingOptions.newlines()]; }
- (NSString*)encoding { return [NSString stringWithCxxString:_encodingOptions.charset()]; }
- (BOOL)useByteOrderMark { return _encodingOptions.byte_order_mark(); }
- (void)setLineEndings:(NSString*)newLineEndings { encodingOptions.set_newlines(to_s(newLineEndings)); }
- (void)setEncoding:(NSString*)newEncoding { encodingOptions.set_charset(to_s(newEncoding)); }
- (void)setUseByteOrderMark:(BOOL)newUseByteOrderMark { encodingOptions.set_byte_order_mark(newUseByteOrderMark); }
- (void)setLineEndings:(NSString*)newLineEndings { _encodingOptions.set_newlines(to_s(newLineEndings)); }
- (void)setEncoding:(NSString*)newEncoding { _encodingOptions.set_charset(to_s(newEncoding)); }
- (void)setUseByteOrderMark:(BOOL)newUseByteOrderMark { _encodingOptions.set_byte_order_mark(newUseByteOrderMark); }
@end
@implementation OakSavePanel
+ (void)showWithPath:(NSString*)aPathSuggestion directory:(NSString*)aDirectorySuggestion fowWindow:(NSWindow*)aWindow encoding:(encoding::type const&)encoding completionHandler:(void(^)(NSString* path, encoding::type const& encoding))aCompletionHandler
{
OakEncodingSaveOptionsViewController* optionsViewController = [[[OakEncodingSaveOptionsViewController alloc] initWithEncodingOptions:encoding] autorelease];
OakEncodingSaveOptionsViewController* optionsViewController = [[OakEncodingSaveOptionsViewController alloc] initWithEncodingOptions:encoding];
if(!optionsViewController)
return;

View File

@@ -19,7 +19,7 @@ OAK_DEBUG_VAR(OakSubmenuController);
@end
@interface OakSubmenuController ()
@property (nonatomic, retain) OakProxyMenuItem* proxyMenuItem;
@property (nonatomic) OakProxyMenuItem* proxyMenuItem;
@end
@implementation OakSubmenuController
@@ -33,7 +33,7 @@ OAK_DEBUG_VAR(OakSubmenuController);
{
[aMenu removeAllItems];
if(id delegate = [NSApp targetForAction:aSelector])
[delegate performSelector:aSelector withObject:aMenu];
[NSApp sendAction:aSelector to:delegate from:aMenu];
else [aMenu addItemWithTitle:@"no items" action:NULL keyEquivalent:@""];
D(DBF_OakSubmenuController, bug("%s\n", [[aMenu description] UTF8String]););
}
@@ -54,7 +54,7 @@ OAK_DEBUG_VAR(OakSubmenuController);
if(eventString < "@0" || "@9" < eventString)
return NO;
NSMenu* dummy = [[NSMenu new] autorelease];
NSMenu* dummy = [NSMenu new];
[self updateMenu:dummy withSelector:@selector(updateGoToMenu:)];
for(NSMenuItem* item in [dummy itemArray])
{
@@ -62,7 +62,7 @@ OAK_DEBUG_VAR(OakSubmenuController);
{
D(DBF_OakSubmenuController, bug("%s%ld\n", sel_getName(item.action), item.tag););
if(!self.proxyMenuItem)
self.proxyMenuItem = [[OakProxyMenuItem new] autorelease];
self.proxyMenuItem = [OakProxyMenuItem new];
self.proxyMenuItem.action = item.action;
self.proxyMenuItem.target = item.target;

View File

@@ -7,9 +7,9 @@ PUBLIC extern NSString* const kUserDefaultsDisableTabBarCollapsingKey;
@protocol OakTabBarViewDelegate, OakTabBarViewDataSource;
PUBLIC @interface OakTabBarView : OakControl
@property (nonatomic, assign, getter = isExpanded) BOOL expanded;
@property (nonatomic, assign) id <OakTabBarViewDelegate> delegate;
@property (nonatomic, assign) id <OakTabBarViewDataSource> dataSource;
@property (nonatomic, getter = isExpanded) BOOL expanded;
@property (nonatomic, weak) id <OakTabBarViewDelegate> delegate;
@property (nonatomic, weak) id <OakTabBarViewDataSource> dataSource;
@property (nonatomic, readonly) NSUInteger countOfVisibleTabs;
- (void)reloadData;
- (void)setSelectedTab:(NSUInteger)anIndex;

View File

@@ -304,11 +304,27 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
}
@interface OakTabBarView ()
{
OBJC_WATCH_LEAKS(OakTabBarView);
NSMutableArray* tabTitles;
NSMutableArray* tabToolTips;
NSMutableArray* tabModifiedStates;
BOOL layoutNeedsUpdate;
NSUInteger selectedTab;
NSUInteger hiddenTab;
layout_metrics_ptr metrics;
std::vector<NSRect> tabRects;
std::map<NSUInteger, value_t> tabDropSpacing;
OakTimer* slideAroundAnimationTimer;
}
- (void)updateLayout;
- (void)selectTab:(id)sender;
@property (nonatomic, retain) OakTimer* slideAroundAnimationTimer;
@property (nonatomic, assign) BOOL layoutNeedsUpdate;
@property (nonatomic, assign) BOOL shouldCollapse;
@property (nonatomic) OakTimer* slideAroundAnimationTimer;
@property (nonatomic) BOOL layoutNeedsUpdate;
@property (nonatomic) BOOL shouldCollapse;
@end
// =================
@@ -316,14 +332,17 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
// =================
@interface OakTabFauxUIElement : NSObject
{
OBJC_WATCH_LEAKS(OakTabFauxUIElement);
}
- (id)initWithTabBarView:(OakTabBarView*)tabBarView index:(NSUInteger)index rect:(NSRect)rect title:(NSString*)title toolTip:(NSString*)toolTip modified:(BOOL)modified selected:(BOOL)selected;
@property (nonatomic, assign) OakTabBarView* tabBarView;
@property (nonatomic, assign) NSUInteger index;
@property (nonatomic, assign) NSRect rect;
@property (nonatomic, retain) NSString* title;
@property (nonatomic, retain) NSString* toolTip;
@property (nonatomic, assign) BOOL modified;
@property (nonatomic, assign) BOOL selected;
@property (nonatomic, weak) OakTabBarView* tabBarView;
@property (nonatomic) NSUInteger index;
@property (nonatomic) NSRect rect;
@property (nonatomic) NSString* title;
@property (nonatomic) NSString* toolTip;
@property (nonatomic) BOOL modified;
@property (nonatomic) BOOL selected;
@end
@implementation OakTabFauxUIElement
@@ -334,21 +353,14 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
_tabBarView = tabBarView;
_index = index;
_rect = rect;
_title = [title retain];
_toolTip = [toolTip retain];
_title = title;
_toolTip = toolTip;
_modified = modified;
_selected = selected;
}
return self;
}
- (void)dealloc
{
self.title = nil;
self.toolTip = nil;
[super dealloc];
}
- (NSString*)description
{
return [NSString stringWithFormat:@"<%@: parent=%@, title=\"%@\", index=%ld, rect=%@>", [self class], self.tabBarView, self.title, self.index, NSStringFromRect(self.rect)];
@@ -380,7 +392,6 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
NSAccessibilityValueAttribute,
NSAccessibilityHelpAttribute,
];
[attributes retain];
}
return attributes;
}
@@ -445,7 +456,6 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
NSAccessibilityPressAction,
NSAccessibilityShowMenuAction,
];
[actions retain];
}
return actions;
}
@@ -488,26 +498,7 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
// ==========================
@implementation OakTabBarView
{
OBJC_WATCH_LEAKS(OakTabBarView);
NSMutableArray* tabTitles;
NSMutableArray* tabToolTips;
NSMutableArray* tabModifiedStates;
BOOL layoutNeedsUpdate;
NSUInteger selectedTab;
NSUInteger hiddenTab;
layout_metrics_ptr metrics;
std::vector<NSRect> tabRects;
std::map<NSUInteger, value_t> tabDropSpacing;
OakTimer* slideAroundAnimationTimer;
id <OakTabBarViewDelegate> delegate;
id <OakTabBarViewDataSource> dataSource;
}
@synthesize delegate, dataSource, slideAroundAnimationTimer, layoutNeedsUpdate;
@synthesize slideAroundAnimationTimer, layoutNeedsUpdate;
- (id)initWithFrame:(NSRect)aRect
{
@@ -530,14 +521,7 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
- (void)dealloc
{
self.slideAroundAnimationTimer = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[tabTitles release];
[tabToolTips release];
[tabModifiedStates release];
[super dealloc];
}
- (void)userDefaultsDidChange:(NSNotification*)aNotification
@@ -696,7 +680,7 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
{
if(self.tag != selectedTab)
{
if(delegate && [delegate respondsToSelector:@selector(tabBarView:shouldSelectIndex:)] && ![delegate tabBarView:self shouldSelectIndex:self.tag])
if(self.delegate && [self.delegate respondsToSelector:@selector(tabBarView:shouldSelectIndex:)] && ![self.delegate tabBarView:self shouldSelectIndex:self.tag])
return;
selectedTab = self.tag;
@@ -706,14 +690,14 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
- (void)didDoubleClickTab:(id)sender
{
if([delegate respondsToSelector:@selector(tabBarView:didDoubleClickIndex:)])
[delegate tabBarView:self didDoubleClickIndex:selectedTab];
if([self.delegate respondsToSelector:@selector(tabBarView:didDoubleClickIndex:)])
[self.delegate tabBarView:self didDoubleClickIndex:selectedTab];
}
- (void)didDoubleClickTabBar:(id)sender
{
if([delegate respondsToSelector:@selector(tabBarViewDidDoubleClick:)])
[delegate tabBarViewDidDoubleClick:self];
if([self.delegate respondsToSelector:@selector(tabBarViewDidDoubleClick:)])
[self.delegate tabBarViewDidDoubleClick:self];
}
- (void)performClose:(id)sender
@@ -727,8 +711,8 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
{
NSPoint pos = [self convertPoint:[anEvent locationInWindow] fromView:nil];
self.tag = [self tagForLayerContainingPoint:pos];
if(self.tag != NSNotFound && [delegate respondsToSelector:@selector(menuForTabBarView:)])
return [delegate menuForTabBarView:self];
if(self.tag != NSNotFound && [self.delegate respondsToSelector:@selector(menuForTabBarView:)])
return [self.delegate menuForTabBarView:self];
return [super menuForEvent:anEvent];
}
@@ -742,19 +726,19 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
- (void)reloadData
{
if(!dataSource)
if(!self.dataSource)
return;
NSMutableArray* titles = [NSMutableArray array];
NSMutableArray* toolTips = [NSMutableArray array];
NSMutableArray* modifiedStates = [NSMutableArray array];
NSUInteger count = [dataSource numberOfRowsInTabBarView:self];
NSUInteger count = [self.dataSource numberOfRowsInTabBarView:self];
for(NSUInteger i = 0; i < count; ++i)
{
[titles addObject:[dataSource tabBarView:self titleForIndex:i]];
[toolTips addObject:[dataSource tabBarView:self toolTipForIndex:i]];
[modifiedStates addObject:@([dataSource tabBarView:self isEditedAtIndex:i])];
[titles addObject:[self.dataSource tabBarView:self titleForIndex:i]];
[toolTips addObject:[self.dataSource tabBarView:self toolTipForIndex:i]];
[modifiedStates addObject:@([self.dataSource tabBarView:self isEditedAtIndex:i])];
}
[tabTitles setArray:titles];
@@ -838,7 +822,7 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
NSUInteger draggedTab = self.tag;
NSRect tabRect = tabRects[draggedTab];
NSImage* image = [[[NSImage alloc] initWithSize:tabRect.size] autorelease];
NSImage* image = [[NSImage alloc] initWithSize:tabRect.size];
[image lockFocus];
uint32_t state = [self currentState] | layer_t::mouse_inside | layer_t::mouse_down;
@@ -849,7 +833,7 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
}
[image unlockFocus];
NSImage* dragImage = [[[NSImage alloc] initWithSize:image.size] autorelease];
NSImage* dragImage = [[NSImage alloc] initWithSize:image.size];
[dragImage lockFocus];
[image drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:0.8];
[dragImage unlockFocus];
@@ -857,7 +841,7 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
[pboard declareTypes:@[ OakTabBarViewTabType ] owner:self];
[pboard setString:[NSString stringWithFormat:@"%lu", draggedTab] forType:OakTabBarViewTabType];
[delegate setupPasteboard:pboard forTabAtIndex:draggedTab];
[self.delegate setupPasteboard:pboard forTabAtIndex:draggedTab];
[self hideTabAtIndex:draggedTab];
[self setDropAreaWidth:[dragImage size].width beforeTabAtIndex:draggedTab animate:NO];
@@ -891,10 +875,10 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
NSDragOperation mask = [sender draggingSourceOperationMask];
NSPoint mousePos = [self convertPoint:[sender draggingLocation] fromView:nil];
BOOL success = [delegate performTabDropFromTabBar:[sender draggingSource]
atIndex:[self dropIndexForMouse:mousePos]
fromPasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
operation:(mask & NSDragOperationMove) ?: (mask & NSDragOperationCopy)];
BOOL success = [self.delegate performTabDropFromTabBar:[sender draggingSource]
atIndex:[self dropIndexForMouse:mousePos]
fromPasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
operation:(mask & NSDragOperationMove) ?: (mask & NSDragOperationCopy)];
return success;
}
@@ -944,7 +928,7 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
NSAccessibilityTabsAttribute,
NSAccessibilityValueAttribute,
]];
attributes = [[set allObjects] retain];
attributes = [set allObjects];
}
return attributes;
}
@@ -968,9 +952,7 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
- (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute
{
if([attribute isEqualToString:NSAccessibilityChildrenAttribute] || [attribute isEqualToString:NSAccessibilityContentsAttribute] || [attribute isEqualToString:NSAccessibilityTabsAttribute])
{
return [self.dataSource numberOfRowsInTabBarView:self];
}
else
return [super accessibilityArrayAttributeCount:attribute];
}
@@ -984,19 +966,19 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
count = index + maxCount;
NSMutableArray *children = [NSMutableArray arrayWithCapacity:count - index];
for(; index < count; ++index)
{
[children addObject:[self accessibilityChildAtIndex:index]];
}
return children;
}
else
{
return [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
}
}
- (NSUInteger)accessibilityIndexOfChild:(id)child
{
OakTabFauxUIElement *element = (OakTabFauxUIElement*)child;
if ([child isMemberOfClass:[OakTabFauxUIElement class]] && element.tabBarView == self)
if([child isMemberOfClass:[OakTabFauxUIElement class]] && element.tabBarView == self)
return element.index;
return NSNotFound;
}
@@ -1007,7 +989,7 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
NSString* title = SafeObjectAtIndex(tabTitles, index);
NSString* toolTip = SafeObjectAtIndex(tabToolTips, index);
BOOL modified = [((NSNumber*)SafeObjectAtIndex(tabModifiedStates, index)) boolValue];
return [[[OakTabFauxUIElement alloc] initWithTabBarView:self index:index rect:rect title:title toolTip:toolTip modified:modified selected:selectedTab==index] autorelease];
return [[OakTabFauxUIElement alloc] initWithTabBarView:self index:index rect:rect title:title toolTip:toolTip modified:modified selected:selectedTab==index];
}
- (id)accessibilityHitTest:(NSPoint)point
@@ -1018,10 +1000,7 @@ static id SafeObjectAtIndex (NSArray* array, NSUInteger index)
iterate(rect, tabRects)
{
if(NSPointInRect(point, *rect))
{
NSUInteger index = rect - tabRects.begin();
return [self accessibilityChildAtIndex:index];
};
return [self accessibilityChildAtIndex:rect - tabRects.begin()];
}
return self;
}

View File

@@ -2,17 +2,6 @@
#import <oak/debug.h>
@interface OakToolTip : NSWindow
{
OBJC_WATCH_LEAKS(OakToolTip);
NSTextField* field;
NSTimer* animationTimer;
NSDate* animationStart;
NSDate* didOpenAtDate; // ignore mouse moves for the next second
NSPoint mousePositionWhenOpened;
BOOL enforceMouseThreshold;
}
- (void)setEnforceMouseThreshold:(BOOL)flag;
- (void)setFont:(NSFont*)aFont;
- (void)setStringValue:(NSString*)aString;

View File

@@ -8,24 +8,34 @@ void OakShowToolTip (NSString* msg, NSPoint location)
{
if(msg)
{
OakToolTip* toolTip = [[OakToolTip new] autorelease];
OakToolTip* toolTip = [OakToolTip new];
[toolTip setStringValue:msg];
[toolTip showAtLocation:location forScreen:nil];
}
}
@interface OakToolTip (Private)
@interface OakToolTip ()
{
OBJC_WATCH_LEAKS(OakToolTip);
NSTextField* field;
NSDate* didOpenAtDate; // ignore mouse moves for the next second
NSPoint mousePositionWhenOpened;
BOOL enforceMouseThreshold;
}
@property (nonatomic) NSTimer* animationTimer;
@property (nonatomic) NSDate* animationStart;
- (void)stopAnimation:(id)anArgument;
@end
@implementation OakToolTip
+ (void)initialize
{
[[NSUserDefaults standardUserDefaults] registerDefaults:
[NSDictionary dictionaryWithObjectsAndKeys:
@1, @"OakToolTipMouseMoveIgnorePeriod",
@5, @"OakToolTipMouseDistanceThreshold",
nil]];
[[NSUserDefaults standardUserDefaults] registerDefaults:@{
@"OakToolTipMouseMoveIgnorePeriod" : @1,
@"OakToolTipMouseDistanceThreshold" : @5,
}];
}
- (id)init
@@ -42,7 +52,7 @@ void OakShowToolTip (NSString* msg, NSPoint location)
[self setHidesOnDeactivate:YES];
[self setIgnoresMouseEvents:YES];
field = [[[NSTextField alloc] initWithFrame:NSZeroRect] autorelease];
field = [[NSTextField alloc] initWithFrame:NSZeroRect];
[field setEditable:NO];
[field setSelectable:NO];
[field setBezeled:NO];
@@ -62,9 +72,6 @@ void OakShowToolTip (NSString* msg, NSPoint location)
- (void)dealloc
{
D(DBF_OakToolTip, bug("\n"););
[self stopAnimation:self];
[didOpenAtDate release];
[super dealloc];
}
- (void)setFont:(NSFont*)aFont
@@ -123,15 +130,16 @@ void OakShowToolTip (NSString* msg, NSPoint location)
- (void)showUntilUserActivityDelayed:(id)sender
{
OakToolTip* retainedSelf = self;
[self orderFront:self];
[self setValue:[NSDate date] forKey:@"didOpenAtDate"];
didOpenAtDate = [NSDate date];
mousePositionWhenOpened = NSZeroPoint;
NSWindow* keyWindow = [[NSApp keyWindow] retain];
NSWindow* keyWindow = [NSApp keyWindow];
if(!keyWindow)
{
keyWindow = [self retain];
keyWindow = self;
[self makeKeyWindow];
}
@@ -163,9 +171,7 @@ void OakShowToolTip (NSString* msg, NSPoint location)
}
[keyWindow setAcceptsMouseMovedEvents:didAcceptMouseMovedEvents];
[keyWindow release];
[self orderOut:nil];
[retainedSelf orderOut:nil];
}
- (void)showAtLocation:(NSPoint)aPoint forScreen:(NSScreen*)aScreen
@@ -191,17 +197,17 @@ void OakShowToolTip (NSString* msg, NSPoint location)
- (void)orderOut:(id)sender
{
if(![self isVisible] || animationTimer)
if(![self isVisible] || self.animationTimer)
return;
[self stopAnimation:self];
[self setValue:[NSDate date] forKey:@"animationStart"];
[self setValue:[NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(animationTick:) userInfo:nil repeats:YES] forKey:@"animationTimer"];
self.animationStart = [NSDate date];
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(animationTick:) userInfo:nil repeats:YES];
}
- (void)animationTick:(id)sender
{
CGFloat alpha = 0.97 * (1 - oak::slow_in_out(-1.5 * [animationStart timeIntervalSinceNow]));
CGFloat alpha = 0.97 * (1 - oak::slow_in_out(-1.5 * [self.animationStart timeIntervalSinceNow]));
if(alpha > 0)
{
[self setAlphaValue:alpha];
@@ -215,13 +221,12 @@ void OakShowToolTip (NSString* msg, NSPoint location)
- (void)stopAnimation:(id)sender
{
if(animationTimer)
if(self.animationTimer)
{
[[self retain] autorelease];
[animationTimer invalidate];
[self setValue:nil forKey:@"animationTimer"];
[self setValue:nil forKey:@"animationStart"];
[self setAlphaValue:0.97];
OakToolTip* retainedSelf = self;
[retainedSelf setAlphaValue:0.97];
[retainedSelf.animationTimer invalidate];
retainedSelf.animationTimer = nil;
}
}
@end

View File

@@ -6,9 +6,5 @@ PUBLIC extern NSUInteger const OakViewWindowIsKeyMask;
PUBLIC extern NSUInteger const OakViewViewIsFirstResponderMask;
PUBLIC @interface OakView : NSView
{
BOOL isFirstResponder;
NSUInteger keyState;
}
@property (nonatomic, assign) NSUInteger keyState;
@property (nonatomic) NSUInteger keyState;
@end

View File

@@ -6,7 +6,9 @@ NSUInteger const OakViewWindowIsKeyMask = 1 << 2;
NSUInteger const OakViewViewIsFirstResponderMask = 1 << 3;
@implementation OakView
@synthesize keyState;
{
BOOL isFirstResponder;
}
- (id)initWithFrame:(NSRect)aFrame
{
@@ -25,7 +27,6 @@ NSUInteger const OakViewViewIsFirstResponderMask = 1 << 3;
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (void)updateKeyState:(NSNotification*)aNotification

View File

@@ -5,12 +5,5 @@
@end
PUBLIC @interface OakWindowFrameHelper : NSObject
{
OBJC_WATCH_LEAKS(OakWindowFrameHelper);
NSWindow* window;
NSString* autosaveName;
Class windowDelegateClass;
}
+ (OakWindowFrameHelper*)windowFrameHelperWithWindow:(NSWindow*)aWindow;
@end

View File

@@ -4,19 +4,22 @@
OAK_DEBUG_VAR(WindowFrameHelper);
@interface OakWindowFrameHelper ()
{
OBJC_WATCH_LEAKS(OakWindowFrameHelper);
Class windowDelegateClass;
}
- (id)initWithWindow:(NSWindow*)aWindow;
- (void)placeAndSizeWindow:(NSWindow*)aWindow;
- (void)snapshotWindowFrame;
@property (nonatomic, retain) NSWindow* window;
@property (nonatomic, retain) NSString* autosaveName;
@property (nonatomic) NSWindow* window;
@property (nonatomic) NSString* autosaveName;
@property (nonatomic) OakWindowFrameHelper* retainedSelf;
@end
@implementation OakWindowFrameHelper
@synthesize window, autosaveName;
+ (OakWindowFrameHelper*)windowFrameHelperWithWindow:(NSWindow*)aWindow
{
return [[[self alloc] initWithWindow:aWindow] autorelease];
return [[self alloc] initWithWindow:aWindow];
}
- (id)initWithWindow:(NSWindow*)aWindow
@@ -26,7 +29,7 @@ OAK_DEBUG_VAR(WindowFrameHelper);
windowDelegateClass = [[aWindow delegate] class];
self.autosaveName = [NSString stringWithFormat:@"%@WindowFrame", NSStringFromClass(windowDelegateClass)];
D(DBF_WindowFrameHelper, bug("Auto-save name: %s\n", [autosaveName UTF8String]););
D(DBF_WindowFrameHelper, bug("Auto-save name: %s\n", [self.autosaveName UTF8String]););
if([[aWindow delegate] isKindOfClass:[NSWindowController class]])
[(NSWindowController*)[aWindow delegate] setShouldCascadeWindows:NO];
@@ -37,35 +40,26 @@ OAK_DEBUG_VAR(WindowFrameHelper);
return self;
}
- (void)dealloc
{
self.window = nil;
self.autosaveName = nil;
[super dealloc];
}
- (void)setWindow:(NSWindow*)newWindow
{
NSWindow* oldWindow = window;
if(oldWindow == newWindow)
if(_window == newWindow)
return;
if(window = [newWindow retain])
if(_window)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMoveOrResize:) name:NSWindowDidMoveNotification object:window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMoveOrResize:) name:NSWindowDidResizeNotification object:window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:window];
[self retain]; // as long as we are observing the window, we want to be retained
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidMoveNotification object:_window];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidResizeNotification object:_window];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowWillCloseNotification object:_window];
}
if(oldWindow)
if(_window = newWindow)
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidMoveNotification object:oldWindow];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidResizeNotification object:oldWindow];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowWillCloseNotification object:oldWindow];
[oldWindow release];
[self release];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMoveOrResize:) name:NSWindowDidMoveNotification object:_window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMoveOrResize:) name:NSWindowDidResizeNotification object:_window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:_window];
}
self.retainedSelf = _window ? self : nil;
}
- (void)windowDidMoveOrResize:(NSNotification*)aNotification
@@ -94,8 +88,8 @@ OAK_DEBUG_VAR(WindowFrameHelper);
- (void)snapshotWindowFrame
{
if((([window styleMask] & NSFullScreenWindowMask) != NSFullScreenWindowMask))
[[NSUserDefaults standardUserDefaults] setObject:NSStringFromRect([self windowFrame:window]) forKey:self.autosaveName];
if((([self.window styleMask] & NSFullScreenWindowMask) != NSFullScreenWindowMask))
[[NSUserDefaults standardUserDefaults] setObject:NSStringFromRect([self windowFrame:self.window]) forKey:self.autosaveName];
}
- (BOOL)ignoreWindow:(NSWindow*)aWindow

View File

@@ -1,13 +1,5 @@
#import <oak/debug.h>
PUBLIC @interface OakZoomingIcon : NSWindow
{
OBJC_WATCH_LEAKS(OakZoomingIcon);
@private
NSRect startFrame;
NSDate* startTime;
NSTimeInterval duration;
NSTimer* animationTimer;
}
+ (void)zoomIcon:(NSImage*)icon fromRect:(NSRect)aRect;
+ (OakZoomingIcon*)zoomIcon:(NSImage*)icon fromRect:(NSRect)aRect;
@end

View File

@@ -1,64 +1,71 @@
#import "OakZoomingIcon.h"
@interface OakZoomingIcon ()
{
OBJC_WATCH_LEAKS(OakZoomingIcon);
}
@property (nonatomic) NSRect startFrame;
@property (nonatomic) NSDate* startTime;
@property (nonatomic) NSTimeInterval duration;
@property (nonatomic) NSTimer* animationTimer;
@end
@implementation OakZoomingIcon
- (id)initWithIcon:(NSImage*)icon rect:(NSRect)aRect
{
if(self = [super initWithContentRect:aRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO])
{
NSImageView* imageView = [[[NSImageView alloc] initWithFrame:aRect] autorelease];
icon = [[icon copy] autorelease];
self.startFrame = aRect;
self.startTime = [NSDate new];
self.duration = ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) ? 4.0 : 0.4;
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
self.releasedWhenClosed = NO;
self.ignoresMouseEvents = YES;
self.backgroundColor = [NSColor clearColor];
self.opaque = NO;
self.level = NSPopUpMenuWindowLevel;
icon = [icon copy];
[icon setSize:NSMakeSize(128, 128)];
NSImageView* imageView = [[NSImageView alloc] initWithFrame:aRect];
[imageView setImage:icon];
[imageView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[self setContentView:imageView];
self.contentView = imageView;
startFrame = aRect;
startTime = [NSDate new];
duration = ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) ? 4.0 : 0.4;
animationTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(tick:) userInfo:nil repeats:YES] retain];
[self setOpaque:NO];
[self setBackgroundColor:[NSColor clearColor]];
[self setLevel:NSPopUpMenuWindowLevel];
[self setIgnoresMouseEvents:YES];
[self orderFront:self];
[self retain];
}
return self;
}
+ (void)zoomIcon:(NSImage*)icon fromRect:(NSRect)aRect
+ (OakZoomingIcon*)zoomIcon:(NSImage*)icon fromRect:(NSRect)aRect
{
[[[OakZoomingIcon alloc] initWithIcon:icon rect:aRect] autorelease];
}
- (void)dealloc
{
[startTime release];
[animationTimer release];
[super dealloc];
return [[OakZoomingIcon alloc] initWithIcon:icon rect:aRect];
}
- (void)tick:(NSTimer*)aTimer
{
NSTimeInterval delta = -[startTime timeIntervalSinceNow];
CGFloat t = std::min(1.0, delta / duration);
NSTimeInterval delta = -[self.startTime timeIntervalSinceNow];
CGFloat t = std::min(1.0, delta / self.duration);
t = log2(5.0*(t) + 1.0) / log2(6.0);
[self setAlphaValue:1.0 - t/1.2];
CGFloat size = 16 + t * (128-16);
NSRect r = NSMakeRect(NSMidX(startFrame) - 0.5 * size, NSMidY(startFrame) - 0.5 * size, size, size);
NSRect r = NSMakeRect(NSMidX(self.startFrame) - 0.5 * size, NSMidY(self.startFrame) - 0.5 * size, size, size);
CGFloat offset = round(0.5 * size);
r = NSMakeRect(
round(NSMidX(startFrame) - offset),
round(NSMidY(startFrame) - offset),
round(NSMidX(self.startFrame) - offset),
round(NSMidY(self.startFrame) - offset),
(2 * offset), (2 * offset));
[self setFrame:r display:YES];
if(delta > duration)
if(delta > self.duration)
{
[animationTimer invalidate];
[self close];
[self.animationTimer invalidate];
self.animationTimer = nil;
}
}
@end

View File

@@ -22,11 +22,7 @@ struct objc_ptr
void reset (T object)
{
if(M_object != object)
{
[M_object release];
M_object = object ? [object retain] : nil;
}
M_object = object;
}
};

View File

@@ -4,5 +4,3 @@ TEST_SOURCES = tests/*.{cc,mm}
LINK += text ns io OakFoundation regexp scm file
EXPORT = src/*.h
FRAMEWORKS = Carbon Cocoa AudioToolbox Quartz
OBJCXX_FLAGS += -fno-objc-arc

View File

@@ -11,7 +11,7 @@
{
if((self = [super initWithFrame:aRect]))
{
myTextStorage = [@"This is a test. Try press ⌃⌘D on one of these words." retain];
myTextStorage = @"This is a test. Try press ⌃⌘D on one of these words.";
}
return self;
}
@@ -23,10 +23,10 @@
- (NSDictionary*)stringAttributes
{
static NSDictionary* attrs = [[NSDictionary dictionaryWithObjectsAndKeys:
[NSColor blackColor], NSForegroundColorAttributeName,
[NSFont userFixedPitchFontOfSize:12], NSFontAttributeName,
nil] retain];
static NSDictionary* attrs = @{
NSForegroundColorAttributeName : [NSColor blackColor],
NSFontAttributeName : [NSFont userFixedPitchFontOfSize:12]
};
return attrs;
}
@@ -54,7 +54,7 @@
- (NSTextStorage *)textStorage
{
return [[[NSTextStorage alloc] initWithString:myTextStorage attributes:[self stringAttributes]] autorelease];
return [[NSTextStorage alloc] initWithString:myTextStorage attributes:[self stringAttributes]];
}
// ===============
@@ -95,7 +95,7 @@
- (NSAttributedString*)attributedSubstringFromRange:(NSRange)theRange
{
NSAttributedString* res = [[[NSAttributedString alloc] initWithString:[myTextStorage substringWithRange:theRange] attributes:[self stringAttributes]] autorelease];
NSAttributedString* res = [[NSAttributedString alloc] initWithString:[myTextStorage substringWithRange:theRange] attributes:[self stringAttributes]];
NSLog(@"%s %@ %@", sel_getName(_cmd), NSStringFromRange(theRange), res);
return res;
}
@@ -140,7 +140,7 @@ public:
void test_dictionary ()
{
@autoreleasepool {
OakSetupApplicationWithView([[[MyTextView alloc] initWithFrame:NSMakeRect(0, 0, 400, 60)] autorelease], "dictionary");
OakSetupApplicationWithView([[MyTextView alloc] initWithFrame:NSMakeRect(0, 0, 400, 60)], "dictionary");
}
}
};