mirror of
https://github.com/textmate/textmate.git
synced 2026-01-19 19:58:11 -05:00
ARC: Update OakAppKit framework
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <file/encoding.h>
|
||||
#import <file/encoding.h>
|
||||
#import <oak/misc.h>
|
||||
|
||||
PUBLIC @interface OakSavePanel : NSObject
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5,12 +5,5 @@
|
||||
@end
|
||||
|
||||
PUBLIC @interface OakWindowFrameHelper : NSObject
|
||||
{
|
||||
OBJC_WATCH_LEAKS(OakWindowFrameHelper);
|
||||
|
||||
NSWindow* window;
|
||||
NSString* autosaveName;
|
||||
Class windowDelegateClass;
|
||||
}
|
||||
+ (OakWindowFrameHelper*)windowFrameHelperWithWindow:(NSWindow*)aWindow;
|
||||
@end
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user