From f109313d32f137eb228994b0c209a5103f19557a Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Tue, 22 Sep 2009 19:32:23 -0700 Subject: [PATCH 01/58] Reapply desktop differences. Reviewed by me. --- AppKit/CPDocument.j | 24 ++++++---- AppKit/CPDocumentController.j | 19 +++++++- AppKit/CPMenu.j | 4 +- AppKit/CPOpenPanel.j | 86 ++++++++++++++++++++++------------- 4 files changed, 89 insertions(+), 44 deletions(-) diff --git a/AppKit/CPDocument.j b/AppKit/CPDocument.j index 82159b55f..31ce78b0f 100644 --- a/AppKit/CPDocument.j +++ b/AppKit/CPDocument.j @@ -24,6 +24,7 @@ @import @import "CPResponder.j" +@import "CPSavePanel.j" @import "CPViewController.j" @import "CPWindowController.j" @@ -416,7 +417,7 @@ var CPDocumentUntitledCount = 0; // FIXME: Oh man is this every looking for trouble, we need to handle login at the Cappuccino level, with HTTP Errors. _readConnection = [CPURLConnection connectionWithRequest:[CPURLRequest requestWithURL:anAbsoluteURL] delegate:self]; - + _readConnection.session = _CPReadSessionMake(aType, aDelegate, aDidReadSelector, aContextInfo); } @@ -459,17 +460,17 @@ var CPDocumentUntitledCount = 0; _writeRequest = [CPURLRequest requestWithURL:anAbsoluteURL]; - [_writeRequest setHTTPMethod:@"POST"]; + [_writeRequest setHTTPMethod:@"PUT"]; [_writeRequest setHTTPBody:[data string]]; - + [_writeRequest setValue:@"close" forHTTPHeaderField:@"Connection"]; if (aSaveOperation == CPSaveOperation) [_writeRequest setValue:@"true" forHTTPHeaderField:@"x-cappuccino-overwrite"]; - + if (aSaveOperation != CPSaveToOperation) [self updateChangeCount:CPChangeCleared]; - + // FIXME: Oh man is this every looking for trouble, we need to handle login at the Cappuccino level, with HTTP Errors. var connection = [CPURLConnection connectionWithRequest:_writeRequest delegate:self]; @@ -784,16 +785,19 @@ var CPDocumentUntitledCount = 0; */ - (void)saveDocumentAs:(id)aSender { - _documentName = window.prompt("Document Name:"); + var savePanel = [CPSavePanel savePanel], + response = [savePanel runModal]; - if (!_documentName) + if (!response) return; - + + var saveURL = [savePanel filename]; + [[CPNotificationCenter defaultCenter] postNotificationName:CPDocumentWillSaveNotification object:self]; - - [self saveToURL:[self proposedFileURL] ofType:[self fileType] forSaveOperation:CPSaveAsOperation delegate:self didSaveSelector:@selector(document:didSave:contextInfo:) contextInfo:NULL]; + + [self saveToURL:saveURL ofType:[self fileType] forSaveOperation:CPSaveAsOperation delegate:self didSaveSelector:@selector(document:didSave:contextInfo:) contextInfo:NULL]; } /* diff --git a/AppKit/CPDocumentController.j b/AppKit/CPDocumentController.j index 4a8f83724..d336617e7 100644 --- a/AppKit/CPDocumentController.j +++ b/AppKit/CPDocumentController.j @@ -24,6 +24,7 @@ @import @import "CPDocument.j" +@import "CPOpenPanel.j"; var CPSharedDocumentController = nil; @@ -138,11 +139,11 @@ var CPSharedDocumentController = nil; - (CPDocument)openDocumentWithContentsOfURL:(CPURL)anAbsoluteURL display:(BOOL)shouldDisplay error:(CPError)anError { var result = [self documentForURL:anAbsoluteURL]; - + if (!result) { var type = [self typeForContentsOfURL:anAbsoluteURL error:anError]; - + result = [self makeDocumentWithContentsOfURL:anAbsoluteURL ofType:type delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:[CPDictionary dictionaryWithObject:shouldDisplay forKey:@"shouldDisplay"]]; } else if (shouldDisplay) @@ -219,6 +220,20 @@ var CPSharedDocumentController = nil; [self openUntitledDocumentOfType:[[_documentTypes objectAtIndex:0] objectForKey:@"CPBundleTypeName"] display:YES]; } +-(void)openDocument:(id)aSender +{ + var openPanel = [CPOpenPanel openPanel]; + + [openPanel runModalForTypes:nil];//[@"nib", @"xib", @"cib"]]; + + var filenames = [openPanel filenames], + index = 0, + count = [filenames count]; + + for (; index < count; ++index) + [self openDocumentWithContentsOfURL:[CPURL URLWithString:filenames[index]] display:YES error:nil]; +} + // Managing Documents /*! diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index 2434040a7..c343273ab 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -1499,7 +1499,9 @@ var _CPMenuBarWindowBackgroundColor = nil, if (self) { // FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/39-dont-allow-windows-to-go-above-menubar - [self setLevel:-1];//CPTornOffMenuWindowLevel]; + if ([CPPlatform isBrowser]) + [self setLevel:-1];//CPTornOffMenuWindowLevel]; + [self setAutoresizingMask:CPWindowWidthSizable]; var contentView = [self contentView]; diff --git a/AppKit/CPOpenPanel.j b/AppKit/CPOpenPanel.j index 058853416..eca9f3f1e 100644 --- a/AppKit/CPOpenPanel.j +++ b/AppKit/CPOpenPanel.j @@ -2,60 +2,84 @@ @import #include "Platform/Platform.h" -var SharedOpenPanel = nil; @implementation CPOpenPanel : CPPanel { - CPArray _files; - BOOL _canChooseFiles @accessors(property=canChooseFiles); - BOOL _canChooseDirectories @accessors(property=canChooseDirectories); - BOOL _allowsMultipleSelection @accessors(property=allowsMultipleSelection); + JSObject _openPanel; } + (id)openPanel { - if (!SharedOpenPanel) - SharedOpenPanel = [[CPOpenPanel alloc] init]; - - return SharedOpenPanel; + return [[CPOpenPanel alloc] init]; } - (id)init { if (self = [super init]) - { - _files = []; - _canChooseFiles = YES; - } + _openPanel = window.application.createOpenPanel(); return self; } +- (BOOL)canChooseFiles +{ + return _openPanel.canChooseFiles; +} + +- (void)setCanChooseFiles:(BOOL)shouldChooseFiles +{ + _openPanel.canChooseFiles = shouldChooseFiles; +} + +- (BOOL)canChooseDirectories +{ + return _openPanel.canChooseDirectories; +} + +- (void)setCanChooseDirectories:(BOOL)shouldChooseDirectories +{ + _openPanel.canChooseDirectories = shouldChooseDirectories; +} + +- (BOOL)resolvesAliases +{ + return _openPanel.resolvesAliases; +} + +- (BOOL)setResolvesAliases:(BOOL)shouldResolveAliases +{ + return _openPanel.resolvesAliases = shouldResolveAliases; +} + +- (BOOL)allowsMultipleSelections +{ + return _openPanel.resolvesAliases; +} + +- (BOOL)setAllowsMultipleSelections:(BOOL)shouldAllowMultipleSelection +{ + return _openPanel.allowsMultipleSelection = shouldAllowMultipleSelection; +} + - (void)filenames { - return _files; + return _openPanel.filenames; } -- (unsigned)runModalForDirectory:(CPString)absoluteDirectoryPath file:(CPString)filename types:(CPArray)fileTypes +- (CPInteger)runModalForDirectory:(CPString)anAbsoluteDirectoryPath file:(CPString)aFilename types:(CPArray)fileTypes { -#if PLATFORM(DOM) - if (window.Titanium) - { - _files = Titanium.Desktop.openFiles({ - path:absoluteDirectoryPath, - types:fileTypes, - multiple:_allowsMultipleSelection, - filename:filename, - directories:_canChooseDirectories, - files:_canChooseFiles - }); - } -#endif + // FIXME: Is this correct??? + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; + + return _openPanel.runModal(anAbsoluteDirectoryPath, aFilename, fileTypes); } -- (unsigned)runModalForTypes:(CPArray)fileTypes -{alert("HERE"); - [self runModalForDirectory:"/" file:nil types:fileTypes]; +- (CPInteger)runModalForTypes:(CPArray)fileTypes +{ + // FIXME: Is this correct??? + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; + + return _openPanel.runModal(fileTypes); } @end From ebbf3c45761c07de788d2457a1e90e9c119e42c8 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Tue, 22 Sep 2009 19:32:53 -0700 Subject: [PATCH 02/58] More desktop differences. Reviewed by me. --- AppKit/CPSavePanel.j | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 AppKit/CPSavePanel.j diff --git a/AppKit/CPSavePanel.j b/AppKit/CPSavePanel.j new file mode 100644 index 000000000..7813cbe40 --- /dev/null +++ b/AppKit/CPSavePanel.j @@ -0,0 +1,44 @@ + +@import + + +@implementation CPSavePanel : CPPanel +{ + JSObject _savePanel; +} + ++ (id)savePanel +{ + return [[CPSavePanel alloc] init]; +} + +- (id)init +{ + if (self = [super init]) + _savePanel = window.application.createSavePanel(); + + return self; +} + +- (CPInteger)runModal +{ + // FIXME: Is this correct??? + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; + + return _savePanel.runModal(); +} + +- (CPInteger)runModalForDirectory:(CPString)anAbsoluteDirectoryPath +{ + // FIXME: Is this correct??? + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; + + return _savePanel.runModal(anAbsoluteDirectoryPath); +} + +- (CPString)filename +{ + return _savePanel.filename; +} + +@end From fce91c7ad3c534d6eb26ce298722730819b90d36 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Sat, 17 Oct 2009 10:00:50 -0700 Subject: [PATCH 03/58] Cleanuped up open/save panel. Reviewed by me. --- AppKit/CPDocument.j | 2 +- AppKit/CPDocumentController.j | 12 +++--- AppKit/CPOpenPanel.j | 79 ++++++++--------------------------- AppKit/CPSavePanel.j | 26 +++--------- 4 files changed, 31 insertions(+), 88 deletions(-) diff --git a/AppKit/CPDocument.j b/AppKit/CPDocument.j index 31ce78b0f..abf06fb9c 100644 --- a/AppKit/CPDocument.j +++ b/AppKit/CPDocument.j @@ -791,7 +791,7 @@ var CPDocumentUntitledCount = 0; if (!response) return; - var saveURL = [savePanel filename]; + var saveURL = [savePanel URL]; [[CPNotificationCenter defaultCenter] postNotificationName:CPDocumentWillSaveNotification diff --git a/AppKit/CPDocumentController.j b/AppKit/CPDocumentController.j index d336617e7..7011c7902 100644 --- a/AppKit/CPDocumentController.j +++ b/AppKit/CPDocumentController.j @@ -223,15 +223,15 @@ var CPSharedDocumentController = nil; -(void)openDocument:(id)aSender { var openPanel = [CPOpenPanel openPanel]; - - [openPanel runModalForTypes:nil];//[@"nib", @"xib", @"cib"]]; - - var filenames = [openPanel filenames], + + [openPanel runModal]; + + var URLs = [openPanel URLs], index = 0, - count = [filenames count]; + count = [URLs count]; for (; index < count; ++index) - [self openDocumentWithContentsOfURL:[CPURL URLWithString:filenames[index]] display:YES error:nil]; + [self openDocumentWithContentsOfURL:[CPURL URLWithString:URLs[index]] display:YES error:nil]; } // Managing Documents diff --git a/AppKit/CPOpenPanel.j b/AppKit/CPOpenPanel.j index eca9f3f1e..8cff33aed 100644 --- a/AppKit/CPOpenPanel.j +++ b/AppKit/CPOpenPanel.j @@ -5,7 +5,11 @@ @implementation CPOpenPanel : CPPanel { - JSObject _openPanel; + BOOL _canChooseFiles @accessors(property=canChooseFiles); + BOOL _canChooseDirectories @accessors(property=canChooseDirectories); + BOOL _allowsMultipleSelection @accessors(property=allowsMultipleSelection); + CPURL _directoryURL @accessors(property=directoryURL); + CPArray _URLs; } + (id)openPanel @@ -13,73 +17,26 @@ return [[CPOpenPanel alloc] init]; } -- (id)init -{ - if (self = [super init]) - _openPanel = window.application.createOpenPanel(); - - return self; -} - -- (BOOL)canChooseFiles -{ - return _openPanel.canChooseFiles; -} - -- (void)setCanChooseFiles:(BOOL)shouldChooseFiles -{ - _openPanel.canChooseFiles = shouldChooseFiles; -} - -- (BOOL)canChooseDirectories -{ - return _openPanel.canChooseDirectories; -} - -- (void)setCanChooseDirectories:(BOOL)shouldChooseDirectories -{ - _openPanel.canChooseDirectories = shouldChooseDirectories; -} - -- (BOOL)resolvesAliases -{ - return _openPanel.resolvesAliases; -} - -- (BOOL)setResolvesAliases:(BOOL)shouldResolveAliases -{ - return _openPanel.resolvesAliases = shouldResolveAliases; -} - -- (BOOL)allowsMultipleSelections -{ - return _openPanel.resolvesAliases; -} - -- (BOOL)setAllowsMultipleSelections:(BOOL)shouldAllowMultipleSelection -{ - return _openPanel.allowsMultipleSelection = shouldAllowMultipleSelection; -} - -- (void)filenames -{ - return _openPanel.filenames; -} - -- (CPInteger)runModalForDirectory:(CPString)anAbsoluteDirectoryPath file:(CPString)aFilename types:(CPArray)fileTypes +- (CPInteger)runModal { // FIXME: Is this correct??? [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; - return _openPanel.runModal(anAbsoluteDirectoryPath, aFilename, fileTypes); + var options = { directoryURL: [self directoryURL], + canChooseFiles: [self canChooseFiles], + canChooseDirectories: [self canChooseDirectories], + allowsMultipleSelection: [self allowsMultipleSelection] }; + + var result = window.cpOpenPanel(options); + + _URLs = result.URLs; + + return result.button; } -- (CPInteger)runModalForTypes:(CPArray)fileTypes +- (CPArray)URLs { - // FIXME: Is this correct??? - [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; - - return _openPanel.runModal(fileTypes); + return _URLs; } @end diff --git a/AppKit/CPSavePanel.j b/AppKit/CPSavePanel.j index 7813cbe40..bc99c3699 100644 --- a/AppKit/CPSavePanel.j +++ b/AppKit/CPSavePanel.j @@ -4,7 +4,7 @@ @implementation CPSavePanel : CPPanel { - JSObject _savePanel; + Object result; } + (id)savePanel @@ -12,33 +12,19 @@ return [[CPSavePanel alloc] init]; } -- (id)init -{ - if (self = [super init]) - _savePanel = window.application.createSavePanel(); - - return self; -} - - (CPInteger)runModal { // FIXME: Is this correct??? [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; - return _savePanel.runModal(); + result = window.cpSavePanel(); + + return result.button; } -- (CPInteger)runModalForDirectory:(CPString)anAbsoluteDirectoryPath +- (CPURL)URL { - // FIXME: Is this correct??? - [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; - - return _savePanel.runModal(anAbsoluteDirectoryPath); -} - -- (CPString)filename -{ - return _savePanel.filename; + return [CPURL URLWithString:result.URL]; } @end From 6076185da7bdd76edc1b2b8fc861a3b4ad72fc00 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Sun, 18 Oct 2009 17:35:53 -0700 Subject: [PATCH 04/58] Added application activation. Reviewed by me. --- AppKit/CPApplication.j | 5 +++++ AppKit/CPWindow/CPWindow.j | 2 ++ AppKit/Platform/CPPlatform.j | 8 ++++++++ 3 files changed, 15 insertions(+) diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 72f88a420..717d02993 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -298,6 +298,11 @@ CPRunContinuesResponse = -1002; [CPPlatform terminateApplication]; } +- (void)activateIgnoringOtherApps:(BOOL)shouldIgnoreOtherApps +{ + [CPPlatform activateIgnoringOtherApps:shouldIgnoreOtherApps]; +} + /*! Calls \c -finishLaunching method which results in starting the main event loop. diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 2c0c0693d..58f051a88 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1264,6 +1264,8 @@ CPTexturedBackgroundWindowMask if (_leftMouseDownView != _firstResponder && [_leftMouseDownView acceptsFirstResponder]) [self makeFirstResponder:_leftMouseDownView]; + [CPApp activateIgnoringOtherApps:YES]; + var theWindow = [anEvent window]; if ([theWindow isKeyWindow] || [theWindow becomesKeyOnlyIfNeeded]) diff --git a/AppKit/Platform/CPPlatform.j b/AppKit/Platform/CPPlatform.j index 851e538bc..a5eac3712 100644 --- a/AppKit/Platform/CPPlatform.j +++ b/AppKit/Platform/CPPlatform.j @@ -45,4 +45,12 @@ window.cpTerminate(); } ++ (void)activateIgnoringOtherApps:(BOOL)shouldIgnoreOtherApps +{ +#if PLATFORM(DOM) + if (typeof window["cpActivateIgnoringOtherApps"] === "function") + window.cpActivateIgnoringOtherApps(!!shouldIgnoreOtherApps); +#endif +} + @end From efaff961684b0f9432d62a4d559d363c1dd1e88f Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Mon, 19 Oct 2009 16:52:19 -0700 Subject: [PATCH 05/58] Consolidate with browser branch. Reviewed by me. --- AppKit/CPDocument.j | 7 ++++++- AppKit/CPMenu.j | 7 +++---- AppKit/CPOpenPanel.j | 24 ++++++++++++++---------- AppKit/CPSavePanel.j | 22 ++++++++++++++++++---- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/AppKit/CPDocument.j b/AppKit/CPDocument.j index abf06fb9c..57f77452c 100644 --- a/AppKit/CPDocument.j +++ b/AppKit/CPDocument.j @@ -460,7 +460,12 @@ var CPDocumentUntitledCount = 0; _writeRequest = [CPURLRequest requestWithURL:anAbsoluteURL]; - [_writeRequest setHTTPMethod:@"PUT"]; + // FIXME: THIS IS WRONG! We need a way to decide + if ([CPPlatform isBrowser]) + [_writeRequest setHTTPMethod:@"POST"]; + else + [_writeRequest setHTTPMethod:@"PUT"]; + [_writeRequest setHTTPBody:[data string]]; [_writeRequest setValue:@"close" forHTTPHeaderField:@"Connection"]; diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index 52376975f..41c8689e7 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -1492,7 +1492,8 @@ var _CPMenuBarWindowBackgroundColor = nil, - (id)init { - var contentRect = [CPPlatform isBrowser] ? [[CPPlatformWindow primaryPlatformWindow] contentBounds] : [[self screen] visibleFrame]; + // This only shows up in browser land, so don't bother calculating metrics in desktop. + var contentRect = [[CPPlatformWindow primaryPlatformWindow] contentBounds]; contentRect.size.height = MENUBAR_HEIGHT; @@ -1501,9 +1502,7 @@ var _CPMenuBarWindowBackgroundColor = nil, if (self) { // FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/39-dont-allow-windows-to-go-above-menubar - if ([CPPlatform isBrowser]) - [self setLevel:-1];//CPTornOffMenuWindowLevel]; - + [self setLevel:-1];//CPTornOffMenuWindowLevel]; [self setAutoresizingMask:CPWindowWidthSizable]; var contentView = [self contentView]; diff --git a/AppKit/CPOpenPanel.j b/AppKit/CPOpenPanel.j index 8cff33aed..e8c2fe676 100644 --- a/AppKit/CPOpenPanel.j +++ b/AppKit/CPOpenPanel.j @@ -1,6 +1,5 @@ @import -#include "Platform/Platform.h" @implementation CPOpenPanel : CPPanel @@ -19,19 +18,24 @@ - (CPInteger)runModal { - // FIXME: Is this correct??? - [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; + if (typeof window["cpOpenPanel"] === "function") + { + // FIXME: Is this correct??? + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; - var options = { directoryURL: [self directoryURL], - canChooseFiles: [self canChooseFiles], - canChooseDirectories: [self canChooseDirectories], - allowsMultipleSelection: [self allowsMultipleSelection] }; + var options = { directoryURL: [self directoryURL], + canChooseFiles: [self canChooseFiles], + canChooseDirectories: [self canChooseDirectories], + allowsMultipleSelection: [self allowsMultipleSelection] }; - var result = window.cpOpenPanel(options); + var result = window.cpOpenPanel(options); - _URLs = result.URLs; + _URLs = result.URLs; - return result.button; + return result.button; + } + + throw "-runModal is unimplemented."; } - (CPArray)URLs diff --git a/AppKit/CPSavePanel.j b/AppKit/CPSavePanel.j index bc99c3699..f8e888d8d 100644 --- a/AppKit/CPSavePanel.j +++ b/AppKit/CPSavePanel.j @@ -4,7 +4,7 @@ @implementation CPSavePanel : CPPanel { - Object result; + CPURL _URL; } + (id)savePanel @@ -17,14 +17,28 @@ // FIXME: Is this correct??? [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; - result = window.cpSavePanel(); + if (typeof window["cpSavePanel"] === "function") + { + var resultObject = window.cpSavePanel(), + result = resultObject.button; - return result.button; + _URL = result ? [CPURL URLWithString:resultObject.URL] : nil; + } + else + { + // FIXME: This is not the best way to do this. + var documentName = window.prompt("Document Name:"), + result = documentName !== null; + + _URL = result ? [[self class] proposedFileURLWithDocumentName:documentName] : nil; + } + + return result; } - (CPURL)URL { - return [CPURL URLWithString:result.URL]; + return _URL; } @end From 0af70c04a044573a235fc78fe58a02500f476d6d Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Wed, 21 Oct 2009 21:01:49 -0700 Subject: [PATCH 06/58] Fixed a bug where windows would not become visible again after closing their platform windows. Reviewed by me. --- AppKit/Platform/DOM/CPDOMWindowLayer.j | 7 +++-- AppKit/Platform/DOM/CPPlatformWindow+DOM.j | 32 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/AppKit/Platform/DOM/CPDOMWindowLayer.j b/AppKit/Platform/DOM/CPDOMWindowLayer.j index 3d6f3dede..a41fa4cc9 100644 --- a/AppKit/Platform/DOM/CPDOMWindowLayer.j +++ b/AppKit/Platform/DOM/CPDOMWindowLayer.j @@ -68,7 +68,7 @@ count = _windows.length - 1; CPDOMDisplayServerRemoveChild(_DOMElement, aWindow._DOMElement); - + [_windows removeObjectAtIndex:aWindow._index]; for (; index < count; ++index) @@ -107,11 +107,12 @@ _windows[zIndex]._index = zIndex; _windows[zIndex]._DOMElement.style.zIndex = zIndex; } + // If the window is not already a resident of this layer, add it. - if (!isVisible) + if (aWindow._DOMElement.parentNode !== _DOMElement) { CPDOMDisplayServerAppendChild(_DOMElement, aWindow._DOMElement); - + aWindow._isVisible = YES; if ([aWindow isFullBridge]) diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index 49a4cab15..0e74c3c0f 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -192,6 +192,8 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; // Make sure the pastboard element is blurred. _DOMPasteboardElement.blur(); + [self _addLayers]; + var theClass = [self class], dragEventImplementation = class_getMethodImplementation(theClass, @selector(dragEvent:)), @@ -250,6 +252,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; _DOMWindow.addEventListener("unload", function() { [self updateFromNativeContentRect]; + [self _removeLayers]; theDocument.removeEventListener("mouseup", mouseEventCallback, NO); theDocument.removeEventListener("mousedown", mouseEventCallback, NO); @@ -296,6 +299,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; _DOMWindow.attachEvent("onbeforeunload", function() { [self updateFromNativeContentRect]; + [self _removeLayers]; theDocument.removeEvent("onmouseup", mouseEventCallback); theDocument.removeEvent("onmousedown", mouseEventCallback); @@ -904,6 +908,34 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; [layer insertWindow:aWindow atIndex:(otherWindow ? (aPlace == CPWindowAbove ? otherWindow._index + 1 : otherWindow._index) : CPNotFound)]; } +- (void)_removeLayers +{ + var levels = _windowLevels, + layers = _windowLayers, + levelCount = levels.length; + + while (levelCount--) + { + var layer = [layers objectForKey:levels[levelCount]]; + + _DOMBodyElement.removeChild(layer._DOMElement); + } +} + +- (void)_addLayers +{ + var levels = _windowLevels, + layers = _windowLayers, + levelCount = levels.length; + + while (levelCount--) + { + var layer = [layers objectForKey:levels[levelCount]]; + + _DOMBodyElement.appendChild(layer._DOMElement); + } +} + /* @ignore */ - (id)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard { From 891d2a28c10cbb50dbf0ed95159cbdde61b2874f Mon Sep 17 00:00:00 2001 From: Seth Buntin Date: Sun, 18 Oct 2009 19:10:27 -0500 Subject: [PATCH 07/58] implement CPException tests --- Tests/Foundation/CPExceptionTest.j | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Tests/Foundation/CPExceptionTest.j diff --git a/Tests/Foundation/CPExceptionTest.j b/Tests/Foundation/CPExceptionTest.j new file mode 100644 index 000000000..6451e32b5 --- /dev/null +++ b/Tests/Foundation/CPExceptionTest.j @@ -0,0 +1,49 @@ +@import + +@implementation CPExceptionTest : OJTestCase +{ +} + +- (void)setUp +{ + exception = [CPException exceptionWithName:@"CPGenericException" + reason:@"Margins must be positive" + userInfo:nil]; +} + +- (void)testInitWithNameReasonUserInfo +{ + var exception = [[CPException alloc] initWithName:@"CPUnsupportedMethodException" + reason:@"setHeaderCell: is not supported. -setHeaderCell:aView instead." + userInfo:nil]; + [self assert:[exception name] equals:"CPUnsupportedMethodException"]; + [self assert:[exception reason] equals:"setHeaderCell: is not supported. -setHeaderCell:aView instead."]; + [self assertThrows:function(){[exception raise]}]; +} + +- (void)testRaiseReason +{ + [self assertThrows:function(){[CPException raise:@"CPGenericException" reason:@"Margins must be positive"];}]; +} + +- (void)testName +{ + [self assert:[exception name] equals:@"CPGenericException"]; +} + +- (void)testReason +{ + [self assert:[exception reason] equals:@"Margins must be positive"]; +} + +- (void)testUserInfo +{ + [self assert:[exception userInfo] equals:null]; +} + +- (void)testRaise +{ + [self assertThrows:function(){[exception raise];}]; +} + +@end From e6d1753e7498f2780a9cda210bfca49cf08b66b5 Mon Sep 17 00:00:00 2001 From: saikat Date: Sat, 17 Oct 2009 17:52:10 -0700 Subject: [PATCH 08/58] Fixed issue with selectText in CPTextField. Closes issue #295 --- AppKit/CPTextField.j | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 0303ee1bb..7994ab75f 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -597,14 +597,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); window.setTimeout(function() { - element.value = [self stringValue]; element.focus(); CPTextFieldInputOwner = self; }, 0.0); //post CPControlTextDidBeginEditingNotification [self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]]; - + element.value = [self stringValue]; + [[[self window] platformWindow] _propagateCurrentDOMEvent:YES]; CPTextFieldInputIsActive = YES; From ee8fef4e8564db2ac20138c790ccb85b362f9165 Mon Sep 17 00:00:00 2001 From: saikat Date: Sat, 17 Oct 2009 15:54:20 -0700 Subject: [PATCH 09/58] Fixes to autosizing behavior for CPMenu - closes issue #270 --- AppKit/CPMenu.j | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index 41c8689e7..1636e7a8f 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -1970,11 +1970,12 @@ var _CPMenuBarWindowBackgroundColor = nil, } } -- (void)setFrameSize:(CGSize)aSize +- (void)setFrame:(CGRect)aRect { - [super setFrameSize:aSize]; - - [self tile]; + var oldSize = CGSizeMakeCopy([self frame].size); + [super setFrame:aRect]; + if (!CGSizeEqualToSize(oldSize, [self frame].size)) + [self tile]; } @end From 341eddb9f94ac33f5f33b1e70cbb959b133abf59 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Thu, 22 Oct 2009 10:20:14 -0700 Subject: [PATCH 10/58] Fixes a tab view bug with removing tabs. Closes #274. Kudos go to jtietema for tracking down the bug. --- AppKit/CPTabView.j | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/AppKit/CPTabView.j b/AppKit/CPTabView.j index 66ad3d3e6..60dd53a3d 100644 --- a/AppKit/CPTabView.j +++ b/AppKit/CPTabView.j @@ -260,9 +260,11 @@ var CPTabViewDidSelectTabViewItemSelector = 1, */ - (void)removeTabViewItem:(CPTabViewItem)aTabViewItem { + var index = [self indexOfTabViewItem:aTabViewItem]; + [_tabViewItems removeObjectIdenticalTo:aTabViewItem]; - [_labelsView tabView:self didRemoveTabViewItem:aTabViewItem]; + [_labelsView tabView:self didRemoveTabViewItemAtIndex:index]; if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector) [_delegate tabViewDidChangeNumberOfTabViewItems:self]; @@ -648,10 +650,9 @@ var _CPTabLabelsViewBackgroundColor = nil, [self layoutSubviews]; } -- (void)tabView:(CPTabView)aTabView didRemoveTabViewItem:(CPTabViewItem)aTabViewItem +- (void)tabView:(CPTabView)aTabView didRemoveTabViewItemAtIndex:(unsigned)index { - var index = [aTabView indexOfTabViewItem:aTabViewItem], - label = _tabLabels[index]; + var label = _tabLabels[index]; [_tabLabels removeObjectAtIndex:index]; From 0561f69c860ce820035a89220695d9ae81081530 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Thu, 22 Oct 2009 19:58:34 -0700 Subject: [PATCH 11/58] Made cancelTracking send a close menu event so that it doesn't behave passively. Reviewed by me. --- AppKit/CPApplication.j | 6 ++ AppKit/CPMenu.j | 117 +++++++++++---------- AppKit/Platform/DOM/CPPlatformWindow+DOM.j | 1 + 3 files changed, 71 insertions(+), 53 deletions(-) diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 717d02993..76e65a768 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -814,6 +814,12 @@ CPRunContinuesResponse = -1002; return [_documentController openDocumentWithContentsOfURL:aFilename display:YES error:NULL]; } +- (void)_didResignActive +{ + if (self._activeMenu) + [self._activeMenu cancelTracking]; +} + @end var _CPModalSessionMake = function(aWindow, aStopCode) diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index 1636e7a8f..3c899a024 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -30,6 +30,7 @@ @import "CPMenuItem.j" @import "CPPanel.j" +#include "CoreGraphics/CGGeometry.h" #include "Platform/Platform.h" @@ -738,7 +739,21 @@ var _CPMenuBarVisible = NO, */ - (void)cancelTracking { - [_menuWindow cancelTracking]; + [[CPRunLoop currentRunLoop] performSelector:@selector(_fireCancelTrackingEvent) target:self argument:nil order:0 modes:[CPDefaultRunLoopMode]]; +} + +- (void)_fireCancelTrackingEvent +{ + [CPApp sendEvent:[CPEvent + otherEventWithType:CPAppKitDefined + location:_CGPointMakeZero() + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:0 + subtype:0 + data1:0 + data2:0]]; } /* @ignore */ @@ -767,7 +782,7 @@ var _CPMenuBarVisible = NO, { var item = _items[index], modifierMask = [item keyEquivalentModifierMask]; - + if ((modifierFlags & (CPShiftKeyMask | CPAlternateKeyMask | CPCommandKeyMask | CPControlKeyMask)) == modifierMask && [characters caseInsensitiveCompare:[item keyEquivalent]] == CPOrderedSame) { @@ -928,7 +943,7 @@ var STICKY_TIME_INTERVAL = 500, */ @implementation _CPMenuWindow : CPWindow { - _CPMenuView _menuView; + _CPMenuView _menuView; CPClipView _menuClipView; CPView _lastMouseOverMenuView; @@ -1178,13 +1193,10 @@ var STICKY_TIME_INTERVAL = 500, [_menuView scrollPoint:CGPointMake(0.0, [self convertBaseToGlobal:clipFrame.origin].y - menuViewOrigin.y)]; } -- (void)cancelTracking -{ - _trackingCanceled = YES; -} - - (void)beginTrackingWithEvent:(CPEvent)anEvent sessionDelegate:(id)aSessionDelegate didEndSelector:(SEL)aDidEndSelector { + CPApp._activeMenu = [_menuView menu]; + _startTime = [anEvent timestamp];//new Date(); _scrollingState = _CPMenuWindowScrollingStateNone; _trackingCanceled = NO; @@ -1198,7 +1210,41 @@ var STICKY_TIME_INTERVAL = 500, - (void)trackEvent:(CPEvent)anEvent { var type = [anEvent type], - theWindow = [anEvent window], + menu = [_menuView menu]; + + // Close Menu Event. + if (type === CPAppKitDefined) + { + // Stop all periodic events at this point. + [CPEvent stopPeriodicEvents]; + + var highlightedItem = [[_menuView menu] highlightedItem]; + + [menu _highlightItemAtIndex:CPNotFound]; + + [self orderOut:self]; + + var delegate = [menu delegate]; + + if ([delegate respondsToSelector:@selector(menuDidClose:)]) + [delegate menuDidClose:menu]; + + if (_sessionDelegate && _didEndSelector) + objj_msgSend(_sessionDelegate, _didEndSelector, self, highlightedItem); + + [[CPNotificationCenter defaultCenter] + postNotificationName:CPMenuDidEndTrackingNotification + object:menu]; + + // Clear these now so its faster next time around. + [_menuView setMenu:nil]; + + CPApp._activeMenu = nil; + + return; + } + + var theWindow = [anEvent window], globalLocation = theWindow ? [theWindow convertBaseToGlobal:[anEvent locationInWindow]] : [anEvent locationInWindow]; if (type === CPPeriodic) @@ -1222,8 +1268,7 @@ var STICKY_TIME_INTERVAL = 500, _lastGlobalLocation = globalLocation; - var menu = [_menuView menu], - menuLocation = [self convertGlobalToBase:globalLocation], + var menuLocation = [self convertGlobalToBase:globalLocation], activeItemIndex = [_menuView itemIndexAtPoint:[_menuView convertPoint:menuLocation fromView:nil]], mouseOverMenuView = [[menu itemAtIndex:activeItemIndex] view]; @@ -1279,47 +1324,11 @@ var STICKY_TIME_INTERVAL = 500, else if (oldScrollingState == _CPMenuWindowScrollingStateNone) [CPEvent startPeriodicEventsAfterDelay:0.0 withPeriod:0.04]; } - else if (type == CPLeftMouseUp && ([anEvent timestamp] - _startTime > STICKY_TIME_INTERVAL)) - { - // Stop these if they're still goin'. - if (_scrollingState != _CPMenuWindowScrollingStateNone) - [CPEvent stopPeriodicEvents]; - - [self cancelTracking]; - } + [menu cancelTracking]; } - - if (_trackingCanceled) - { - // Stop all periodic events at this point. - [CPEvent stopPeriodicEvents]; - - var highlightedItem = [[_menuView menu] highlightedItem]; - - [menu _highlightItemAtIndex:CPNotFound]; - - [self orderOut:self]; - var delegate = [menu delegate]; - - if ([delegate respondsToSelector:@selector(menuDidClose:)]) - [delegate menuDidClose:menu]; - - if (_sessionDelegate && _didEndSelector) - objj_msgSend(_sessionDelegate, _didEndSelector, self, highlightedItem); - - [[CPNotificationCenter defaultCenter] - postNotificationName:CPMenuDidEndTrackingNotification - object:menu]; - - // Clear these now so its faster next time around. - [_menuView setMenu:nil]; - - return; - } - - [CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; + [CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPAppKitDefinedMask untilDate:nil inMode:nil dequeue:YES]; } @end @@ -1970,11 +1979,13 @@ var _CPMenuBarWindowBackgroundColor = nil, } } -- (void)setFrame:(CGRect)aRect +- (void)setFrame:(CGRect)aRect display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate { - var oldSize = CGSizeMakeCopy([self frame].size); - [super setFrame:aRect]; - if (!CGSizeEqualToSize(oldSize, [self frame].size)) + var size = [self frame].size; + + [super setFrame:aRect display:shouldDisplay animate:shouldAnimate]; + + if (_CGSizeEqualToSize(size, aRect.size)) [self tile]; } diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index 0e74c3c0f..5733dac6c 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -338,6 +338,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; if (![CPPlatform isBrowser]) { + _DOMWindow.cpWindowNumber = [self._only windowNumber]; _DOMWindow.cpSetFrame(_contentRect); _DOMWindow.cpSetLevel(_level); _DOMWindow.cpSetHasShadow(_hasShadow); From 24c6f0ec9fc7794dee16dfbbddca78fa2cb115c0 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Sun, 25 Oct 2009 15:32:42 -0700 Subject: [PATCH 12/58] Fix for broken menu sizing. Closes #308. Reviewed by me. --- AppKit/CPMenu.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index 3c899a024..a9cdd64bb 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -1985,7 +1985,7 @@ var _CPMenuBarWindowBackgroundColor = nil, [super setFrame:aRect display:shouldDisplay animate:shouldAnimate]; - if (_CGSizeEqualToSize(size, aRect.size)) + if (!_CGSizeEqualToSize(size, aRect.size)) [self tile]; } From 9ab75eb66228d1a6f693ee43e1e5fdf872c1b74f Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Sun, 25 Oct 2009 17:41:45 -0700 Subject: [PATCH 13/58] Fixes a type which was causing columnWithIdentifier: in CPTableView to be broken. --- AppKit/CPTableView.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index e7113c653..e4588c429 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -538,7 +538,7 @@ CPTableViewSolidHorizontalGridLineMask = 1 << 1; count = NUMBER_OF_COLUMNS(); for (; index < count; ++index) - if ([_tableColumns identifier] === anIdentifier) + if ([_tableColumns[index] identifier] === anIdentifier) return index; return CPNotFound; From de920e959aa9b73424199cb634760d427f2cb4d2 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Sun, 25 Oct 2009 18:49:49 -0700 Subject: [PATCH 14/58] Fix for updating table column header views after they are initially loaded. --- AppKit/CPTableColumn.j | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AppKit/CPTableColumn.j b/AppKit/CPTableColumn.j index 9653af630..8a8f84d33 100644 --- a/AppKit/CPTableColumn.j +++ b/AppKit/CPTableColumn.j @@ -209,6 +209,11 @@ CPTableColumnUserResizingMask = 2; [CPException raise:CPInvalidArgumentException reason:@"Attempt to set nil header view on " + [self description]]; _headerView = aView; + + var tableHeaderView = [_tableView headerView]; + + [tableHeaderView setNeedsLayout]; + [tableHeaderView setNeedsDisplay:YES]; } - (CPView)headerView From 424611e7c724c8fcf7dcc8c7f60cc1774cbabb02 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Tue, 20 Oct 2009 20:51:35 -0400 Subject: [PATCH 15/58] fixed frameRectForContentRect:styleMask: so the styleMask argument is actually used and the method no longer outputs an error when called --- AppKit/CPWindow/CPWindow.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 58f051a88..ab5c48ba3 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -581,7 +581,7 @@ CPTexturedBackgroundWindowMask */ + (CGRect)frameRectForContentRect:(CGRect)aContentRect styleMask:(unsigned)aStyleMask { - return [[[self class] _windowViewClassForStyleMask:_styleMask] frameRectForContentRect:aContentRect]; + return [[[self class] _windowViewClassForStyleMask:aStyleMask] frameRectForContentRect:aContentRect]; } /*! From 86d5ea6c64354f1294307e8d432584384c7559ba Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Tue, 20 Oct 2009 23:32:10 -0400 Subject: [PATCH 16/58] made sheet 10 percent transparent to match Cocoa sheets. --- AppKit/CPWindow/_CPDocModalWindowView.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppKit/CPWindow/_CPDocModalWindowView.j b/AppKit/CPWindow/_CPDocModalWindowView.j index 9db0ee9c7..221fbe011 100644 --- a/AppKit/CPWindow/_CPDocModalWindowView.j +++ b/AppKit/CPWindow/_CPDocModalWindowView.j @@ -11,7 +11,7 @@ var _CPStandardWindowViewBodyBackgroundColor = nil; + (CPColor)bodyBackgroundColor { if (!_CPStandardWindowViewBodyBackgroundColor) - _CPStandardWindowViewBodyBackgroundColor = [CPColor colorWithWhite:0.96 alpha:1.0]; + _CPStandardWindowViewBodyBackgroundColor = [CPColor colorWithWhite:0.96 alpha:0.9]; return _CPStandardWindowViewBodyBackgroundColor; } From b5cdcec0041b97f0fe77eded114142b4a5cc7384 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Tue, 13 Oct 2009 01:54:22 -0400 Subject: [PATCH 17/58] fixed CPSearchField search and cancel buttons so they stay positioned correctly when resized. --- AppKit/CPSearchField.j | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AppKit/CPSearchField.j b/AppKit/CPSearchField.j index 699de2a3a..85ef90282 100644 --- a/AppKit/CPSearchField.j +++ b/AppKit/CPSearchField.j @@ -106,10 +106,12 @@ var CPSearchFieldSearchImage = nil, [_cancelButton setHidden:YES]; + [_cancelButton setAutoresizingMask:CPViewMinXMargin]; [self addSubview:_cancelButton]; _searchButton = [[CPButton alloc] initWithFrame:CPMakeRect(5,(frame.size.height-25)/2,25,25)]; [_searchButton setBezelStyle:CPRegularSquareBezelStyle]; + [_searchButton setAutoresizingMask:CPViewMaxXMargin] [_searchButton setBordered:NO]; [_searchButton setImageScaling:CPScaleToFit]; From b4571199256ce4d2b3e6f1fdb4b53a8e7a77cc9f Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Sun, 25 Oct 2009 23:11:00 -0700 Subject: [PATCH 18/58] Added shadow drawing styles. Reviewed by me. --- AppKit/CPMenu.j | 1 + AppKit/CPWindow/CPWindow.j | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index a9cdd64bb..ad0e2dad7 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -1006,6 +1006,7 @@ var STICKY_TIME_INTERVAL = 500, { [self setLevel:CPPopUpMenuWindowLevel]; [self setHasShadow:YES]; + [self setShadowStyle:CPMenuWindowShadowStyle]; [self setAcceptsMouseMovedEvents:YES]; _unconstrainedFrame = CGRectMakeZero(); diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index ab5c48ba3..ef3eaa277 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1004,6 +1004,7 @@ CPTexturedBackgroundWindowMask - (void)setShadowStyle:(unsigned)aStyle { _shadowStyle = aStyle; + [[self platformWindow] setShadowStyle:_shadowStyle]; } @@ -2380,6 +2381,12 @@ function _CPWindowFullPlatformWindowSessionMake(aWindowView, aContentRect, hasSh return { windowView:aWindowView, contentRect:aContentRect, hasShadow:hasShadow, level:aLevel }; } +CPStandardWindowShadowStyle = 0; +CPMenuWindowShadowStyle = 1; +CPPanelWindowShadowStyle = 2; +CPCustomWindowShadowStyle = 3; + + @import "_CPWindowView.j" @import "_CPStandardWindowView.j" @import "_CPDocModalWindowView.j" From 66b447de7be639c8ca82188d3592a41d373d18e7 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Mon, 26 Oct 2009 16:00:47 -0700 Subject: [PATCH 19/58] Stopped CPWindowController from setting self as next responder of CPDocument. Fixes issue with multi-document windows not sending saveDocument to focused document. Reviewed by me. --- AppKit/CPDocument.j | 3 --- 1 file changed, 3 deletions(-) diff --git a/AppKit/CPDocument.j b/AppKit/CPDocument.j index 57f77452c..f3b721227 100644 --- a/AppKit/CPDocument.j +++ b/AppKit/CPDocument.j @@ -311,10 +311,7 @@ var CPDocumentUntitledCount = 0; [_windowControllers addObject:aWindowController]; if ([aWindowController document] !== self) - { - [aWindowController setNextResponder:self]; [aWindowController setDocument:self]; - } } - (CPView)view From 76edc4f91400a608862e89ff7c98f1180b92eeda Mon Sep 17 00:00:00 2001 From: Tom Robinson Date: Mon, 26 Oct 2009 16:47:09 -0700 Subject: [PATCH 20/58] Use Array(n).join(ch) trick for strings of identical chars --- AppKit/CPTextField.j | 9 +-------- Objective-J/utilities.js | 5 +---- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 7994ab75f..ebf0815c9 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -951,14 +951,7 @@ var secureStringForString = function(aString) // This is true for when aString === "" and null/undefined. if (!aString) return ""; - - var secureString = "", - length = aString.length; - - while (length--) - secureString += CPSecureTextFieldCharacter; - - return secureString; + return Array(aString.length).join(CPSecureTextFieldCharacter); } diff --git a/Objective-J/utilities.js b/Objective-J/utilities.js index ac2e74386..617eb9cbe 100644 --- a/Objective-J/utilities.js +++ b/Objective-J/utilities.js @@ -168,10 +168,7 @@ var _sprintf_justify = function(sign, prefix, string, suffix, width, leftJustify var _sprintf_pad = function(n, ch) { - var result = ""; - for (var i = 0; i < n; i++) - result += ch; - return result; + return Array(Math.max(0,n)).join(ch); } // Base64 encoding and decoding From 717c8520b485ffecfb0b73380b8f130445aa4717 Mon Sep 17 00:00:00 2001 From: Tom Robinson Date: Mon, 26 Oct 2009 16:53:13 -0700 Subject: [PATCH 21/58] Use MAX instead of Math.max --- Objective-J/utilities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objective-J/utilities.js b/Objective-J/utilities.js index 617eb9cbe..31c18333b 100644 --- a/Objective-J/utilities.js +++ b/Objective-J/utilities.js @@ -168,7 +168,7 @@ var _sprintf_justify = function(sign, prefix, string, suffix, width, leftJustify var _sprintf_pad = function(n, ch) { - return Array(Math.max(0,n)).join(ch); + return Array(MAX(0,n)).join(ch); } // Base64 encoding and decoding From 82404265fbb583a5249f53e9aea920190e643b2b Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Mon, 26 Oct 2009 22:18:58 -0700 Subject: [PATCH 22/58] Warn when closing an unsaved document. --- AppKit/CPAlert.j | 34 ++++++++++-------- AppKit/CPDocument.j | 74 +++++++++++++++++++++++++++++++++++--- AppKit/CPWindow/CPWindow.j | 22 ++++++++++-- 3 files changed, 109 insertions(+), 21 deletions(-) diff --git a/AppKit/CPAlert.j b/AppKit/CPAlert.j index 75b63ce9d..b1dc33d0e 100644 --- a/AppKit/CPAlert.j +++ b/AppKit/CPAlert.j @@ -116,21 +116,12 @@ var CPAlertWarningImage, */ - (id)init { - self = [super init]; - - if (self) + if (self = [super init]) { _buttonCount = 0; _buttons = [CPArray array]; _alertStyle = CPWarningAlertStyle; - - _messageLabel = [[CPTextField alloc] initWithFrame:CGRectMake(57.0, 10.0, 220.0, 80.0)]; - [_messageLabel setFont:[CPFont systemFontOfSize:12.0]]; - [_messageLabel setLineBreakMode:CPLineBreakByWordWrapping]; - [_messageLabel setAlignment:CPJustifiedTextAlignment]; - - _alertImageView = [[CPImageView alloc] initWithFrame:CGRectMake(15.0, 12.0, 32.0, 32.0)]; - + [self setWindowStyle:nil]; } @@ -145,12 +136,12 @@ var CPAlertWarningImage, { _windowStyle = styleMask; - _alertPanel = [[CPPanel alloc] initWithContentRect:CGRectMake(0.0, 0.0, 300.0, 130.0) styleMask:styleMask ? styleMask | CPTitledWindowMask : CPTitledWindowMask]; + _alertPanel = [[CPPanel alloc] initWithContentRect:CGRectMake(0.0, 0.0, 400.0, 110.0) styleMask:styleMask ? styleMask | CPTitledWindowMask : CPTitledWindowMask]; [_alertPanel setFloatingPanel:YES]; [_alertPanel center]; - + [_messageLabel setTextColor:(styleMask & CPHUDBackgroundWindowMask) ? [CPColor whiteColor] : [CPColor blackColor]]; - + var count = [_buttons count]; for(var i=0; i < count; i++) { @@ -162,6 +153,18 @@ var CPAlertWarningImage, [[_alertPanel contentView] addSubview:button]; } + if (!_messageLabel) + { + var bounds = [[_alertPanel contentView] bounds]; + + _messageLabel = [[CPTextField alloc] initWithFrame:CGRectMake(57.0, 10.0, CGRectGetWidth(bounds) - 73.0, 62.0)]; + [_messageLabel setFont:[CPFont boldSystemFontOfSize:13.0]]; + [_messageLabel setLineBreakMode:CPLineBreakByWordWrapping]; + [_messageLabel setAlignment:CPJustifiedTextAlignment]; + + _alertImageView = [[CPImageView alloc] initWithFrame:CGRectMake(15.0, 12.0, 32.0, 32.0)]; + } + [[_alertPanel contentView] addSubview:_messageLabel]; [[_alertPanel contentView] addSubview:_alertImageView]; } @@ -251,7 +254,8 @@ var CPAlertWarningImage, */ - (void)addButtonWithTitle:(CPString)title { - var button = [[CPButton alloc] initWithFrame:CGRectMake(200.0 - (_buttonCount * 90.0), 98.0, 80.0, (_windowStyle == CPHUDBackgroundWindowMask) ? 20.0 : 24.0)]; + var bounds = [[_alertPanel contentView] bounds], + button = [[CPButton alloc] initWithFrame:CGRectMake(CGRectGetWidth(bounds) - ((_buttonCount + 1) * 90.0), CGRectGetHeight(bounds) - 34.0, 80.0, (_windowStyle == CPHUDBackgroundWindowMask) ? 20.0 : 24.0)]; [button setTitle:title]; [button setTarget:self]; diff --git a/AppKit/CPDocument.j b/AppKit/CPDocument.j index f3b721227..ee76a1033 100644 --- a/AppKit/CPDocument.j +++ b/AppKit/CPDocument.j @@ -109,6 +109,8 @@ var CPDocumentUntitledCount = 0; CPURLConnection _readConnection; CPURLRequest _writeRequest; + + CPAlert _canCloseAlert; } /*! @@ -529,6 +531,7 @@ var CPDocumentUntitledCount = 0; _writeRequest = nil; objj_msgSend(session.delegate, session.didSaveSelector, self, NO, session.contextInfo); + [self _sendDocumentSavedNotification:NO]; } } } @@ -557,6 +560,7 @@ var CPDocumentUntitledCount = 0; _writeRequest = nil; objj_msgSend(session.delegate, session.didSaveSelector, self, YES, session.contextInfo); + [self _sendDocumentSavedNotification:YES]; } } @@ -584,6 +588,7 @@ var CPDocumentUntitledCount = 0; alert("There was an error saving the document."); objj_msgSend(session.delegate, session.didSaveSelector, self, NO, session.contextInfo); + [self _sendDocumentSavedNotification:NO]; } } @@ -768,6 +773,11 @@ var CPDocumentUntitledCount = 0; @param aSender the object requesting the save */ - (void)saveDocument:(id)aSender +{ + [self saveDocumentWithDelegate:nil didSaveSelector:nil contextInfo:nil]; +} + +- (void)saveDocumentWithDelegate:(id)delegate didSaveSelector:(SEL)didSaveSelector contextInfo:(Object)contextInfo { if (_fileURL) { @@ -775,10 +785,10 @@ var CPDocumentUntitledCount = 0; postNotificationName:CPDocumentWillSaveNotification object:self]; - [self saveToURL:_fileURL ofType:[self fileType] forSaveOperation:CPSaveOperation delegate:self didSaveSelector:@selector(document:didSave:contextInfo:) contextInfo:NULL]; + [self saveToURL:_fileURL ofType:[self fileType] forSaveOperation:CPSaveOperation delegate:delegate didSaveSelector:didSaveSelector contextInfo:contextInfo]; } else - [self saveDocumentAs:self]; + [self _saveDocumentAsWithDelegate:delegate didSaveSelector:didSaveSelector contextInfo:contextInfo]; } /*! @@ -786,6 +796,11 @@ var CPDocumentUntitledCount = 0; @param aSender the object requesting the operation */ - (void)saveDocumentAs:(id)aSender +{ + [self _saveDocumentAsWithDelegate:nil didSaveSelector:nil contextInfo:nil]; +} + +- (void)_saveDocumentAsWithDelegate:(id)delegate didSaveSelector:(SEL)didSaveSelector contextInfo:(Object)contextInfo { var savePanel = [CPSavePanel savePanel], response = [savePanel runModal]; @@ -799,13 +814,13 @@ var CPDocumentUntitledCount = 0; postNotificationName:CPDocumentWillSaveNotification object:self]; - [self saveToURL:saveURL ofType:[self fileType] forSaveOperation:CPSaveAsOperation delegate:self didSaveSelector:@selector(document:didSave:contextInfo:) contextInfo:NULL]; + [self saveToURL:saveURL ofType:[self fileType] forSaveOperation:CPSaveAsOperation delegate:delegate didSaveSelector:didSaveSelector contextInfo:contextInfo]; } /* @ignore */ -- (void)document:(id)aDocument didSave:(BOOL)didSave contextInfo:(id)aContextInfo +- (void)_sendDocumentSavedNotification:(BOOL)didSave { if (didSave) [[CPNotificationCenter defaultCenter] @@ -819,6 +834,57 @@ var CPDocumentUntitledCount = 0; @end +@implementation CPDocument (ClosingDocuments) + +- (void)shouldCloseWindowController:(CPWindowController)controller delegate:(id)delegate shouldCloseSelector:(SEL)selector contextInfo:(Object)info +{ + if ([controller shouldCloseDocument] || ([_windowControllers count] < 2 && [_windowControllers indexOfObject:controller] !== CPNotFound)) + [self canCloseDocumentWithDelegate:delegate shouldCloseSelector:selector contextInfo:info]; + else if ([delegate respondsToSelector:selector]) + objj_msgSend(delegate, selector, self, YES, info); +} + +- (void)canCloseDocumentWithDelegate:(id)aDelegate shouldCloseSelector:(SEL)aSelector contextInfo:(Object)context +{ + if (![self isDocumentEdited]) + return [aDelegate respondsToSelector:aSelector] && objj_msgSend(aDelegate, aSelector, self, YES, context); + + _canCloseAlert = [[CPAlert alloc] init]; + + [_canCloseAlert setDelegate:self]; + [_canCloseAlert setAlertStyle:CPWarningAlertStyle]; + [_canCloseAlert setTitle:@"Unsaved Document"]; + [_canCloseAlert setMessageText:sprintf(@"Do you want to save the changes you've made to the document \"%@\"?", + [self displayName] || [self fileName])]; + + [_canCloseAlert addButtonWithTitle:@"Save"]; + [_canCloseAlert addButtonWithTitle:@"Cancel"]; + [_canCloseAlert addButtonWithTitle:@"Don't Save"]; + + _canCloseAlert._context = {delegate:aDelegate, selector:aSelector, context:context}; + + [_canCloseAlert runModal]; +} + +- (void)alertDidEnd:(CPAlert)alert returnCode:(int)returnCode +{ + if (alert !== _canCloseAlert) + return; + + var delegate = alert._context.delegate, + selector = alert._context.selector, + context = alert._context.context; + + if (returnCode === 0) + [self saveDocumentWithDelegate:delegate didSaveSelector:selector contextInfo:context]; + else + objj_msgSend(delegate, selector, self, returnCode === 2, context); + + _canCloseAlert = nil; +} + +@end + var _CPReadSessionMake = function(aType, aDelegate, aDidReadSelector, aContextInfo) { return { fileType:aType, delegate:aDelegate, didReadSelector:aDidReadSelector, contextInfo:aContextInfo }; diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index ef3eaa277..83fdb8a9f 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1636,6 +1636,9 @@ CPTexturedBackgroundWindowMask */ - (void)performClose:(id)aSender { + if (!(_styleMask & CPClosableWindowMask)) + return; + // Only send ONE windowShouldClose: message. if ([_delegate respondsToSelector:@selector(windowShouldClose:)]) { @@ -1646,8 +1649,23 @@ CPTexturedBackgroundWindowMask // Only check self is delegate does NOT implement this. This also ensures this when delegate == self (returns true). else if ([self respondsToSelector:@selector(windowShouldClose:)] && ![self windowShouldClose:self]) return; - - [self close]; + + var document = [_windowController document]; + if (document) + { + [document shouldCloseWindowController:_windowController + delegate:self + shouldCloseSelector:@selector(_document:shouldClose:contextInfo:) + contextInfo:nil]; + } + else + [self close]; +} + +- (void)_document:(CPDocument)document shouldClose:(BOOL)shouldClose contextInfo:(Object)context +{ + if (shouldClose) + [self close]; } /*! From 7b14f41cd8ab3be93efceacfe9014b646c7b8484 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Mon, 26 Oct 2009 22:43:51 -0700 Subject: [PATCH 23/58] Added CGRectNull support to CGRectUnion. Reviewed by me. --- AppKit/CoreGraphics/CGGeometry.j | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/AppKit/CoreGraphics/CGGeometry.j b/AppKit/CoreGraphics/CGGeometry.j index a046638fe..3c2902ddb 100644 --- a/AppKit/CoreGraphics/CGGeometry.j +++ b/AppKit/CoreGraphics/CGGeometry.j @@ -70,6 +70,8 @@ _function(CGInsetMakeZero()) _function(CGInsetMakeCopy(anInset)) _function(CGInsetIsEmpty(anInset)) +CGRectNull = _CGRectMake(Infinity, Infinity, 0.0, 0.0); + /*! @addtogroup appkit @{ @@ -174,6 +176,15 @@ function CGRectStandardize(aRect) function CGRectUnion(lhsRect, rhsRect) { + var lhsRectIsNull = !lhsRect || lhsRect === CGRectNull, + rhsRectIsNull = !rhsRect || rhsRect === CGRectNull; + + if (lhsRectIsNull) + return rhsRectIsNull ? CGRectNull : rhsRect; + + if (rhsRectIsNull) + return lhsRectIsNull ? CGRectNull : lhsRect; + var minX = MIN(_CGRectGetMinX(lhsRect), _CGRectGetMinX(rhsRect)), minY = MIN(_CGRectGetMinY(lhsRect), _CGRectGetMinY(rhsRect)), maxX = MAX(_CGRectGetMaxX(lhsRect), _CGRectGetMaxX(rhsRect)), From 9e825ea62ed208026e1e30162e4c5f032446ce5f Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Mon, 26 Oct 2009 23:20:05 -0700 Subject: [PATCH 24/58] Add close to CPDocument --- AppKit/CPDocument.j | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/AppKit/CPDocument.j b/AppKit/CPDocument.j index ee76a1033..3582a705b 100644 --- a/AppKit/CPDocument.j +++ b/AppKit/CPDocument.j @@ -836,6 +836,12 @@ var CPDocumentUntitledCount = 0; @implementation CPDocument (ClosingDocuments) +- (void)close +{ + [_windowControllers makeObjectsPerformSelector:@selector(close)]; + [[CPDocumentController sharedDocumentController] removeDocument:self]; +} + - (void)shouldCloseWindowController:(CPWindowController)controller delegate:(id)delegate shouldCloseSelector:(SEL)selector contextInfo:(Object)info { if ([controller shouldCloseDocument] || ([_windowControllers count] < 2 && [_windowControllers indexOfObject:controller] !== CPNotFound)) From 315e0eac0c510d583f458aa0ee03255f925e1830 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Tue, 27 Oct 2009 14:55:06 -0700 Subject: [PATCH 25/58] Removed remaining references to full bridge in window template. Reviewed by me. --- AppKit/Cib/_CPCibWindowTemplate.j | 36 +++++++++++++++++++------------ 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/AppKit/Cib/_CPCibWindowTemplate.j b/AppKit/Cib/_CPCibWindowTemplate.j index f7880e5d1..47763f774 100644 --- a/AppKit/Cib/_CPCibWindowTemplate.j +++ b/AppKit/Cib/_CPCibWindowTemplate.j @@ -2,18 +2,19 @@ @import -var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey", - _CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey", +var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey", + _CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey", - _CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey", - _CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey", + _CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey", + _CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey", - _CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey", - _CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey", - _CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey", - _CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey", + _CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey", + _CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey", + _CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey", + _CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey", - _CPCibWindowTemplateWindowIsFullBridgeKey = @"_CPCibWindowTemplateWindowIsFullBridgeKey"; + _CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop = @"_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop"; + _CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey"; @implementation _CPCibWindowTemplate : CPObject { @@ -30,7 +31,8 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeK CPString _windowTitle; CPView _windowView; - BOOL _windowIsFullBridge; + BOOL _windowAutorecalculatesKeyViewLoop; + BOOL _windowIsFullPlatformWindow; } - (id)init @@ -46,7 +48,7 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeK _windowTitle = @"Window"; _windowView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 400.0, 200.0)]; - _windowIsFullBridge = NO; + _windowIsFullPlatformWindow = NO; } return self; @@ -72,7 +74,8 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeK _windowTitle = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowTitleKey]; _windowView = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowViewKey]; - _windowIsFullBridge = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowIsFullBridgeKey]; + _windowAutorecalculatesKeyViewLoop = !![aCoder decodeObjectForKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop]; + _windowIsFullPlatformWindow = !![aCoder decodeObjectForKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey]; } return self; @@ -94,7 +97,11 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeK [aCoder encodeObject:_windowTitle forKey:_CPCibWindowTemplateWindowTitleKey]; [aCoder encodeObject:_windowView forKey:_CPCibWindowTemplateWindowViewKey]; - [aCoder encodeObject:_windowIsFullBridge forKey:_CPCibWindowTemplateWindowIsFullBridgeKey]; + if (_windowAutorecalculatesKeyViewLoop) + [aCoder encodeObject:_windowAutorecalculatesKeyViewLoop forKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop]; + + if (_windowIsFullPlatformWindow) + [aCoder encodeObject:_windowIsFullPlatformWindow forKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey]; } - (CPString)customClassName @@ -144,7 +151,8 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeK [theWindow setToolbar:_viewClass]; } - [theWindow setFullBridge:_windowIsFullBridge]; + [theWindow setAutorecalculatesKeyViewLoop:_windowAutorecalculatesKeyViewLoop]; + [theWindow setFullBridge:_windowIsFullPlatformWindow]; return theWindow; } From b2d994bd66de498b7bc32148400c288cd5617736 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Tue, 27 Oct 2009 17:36:46 -0700 Subject: [PATCH 26/58] Adds support for warning before closing documents that have unsaved changes. Includes changes to the multiple documents per window controller stuff. --- AppKit/CPAlert.j | 6 ++--- AppKit/CPDocument.j | 8 +++--- AppKit/CPWindow/CPWindow.j | 50 +++++++++++++++++++++--------------- AppKit/CPWindowController.j | 51 +++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 27 deletions(-) diff --git a/AppKit/CPAlert.j b/AppKit/CPAlert.j index b1dc33d0e..6f5b3cefd 100644 --- a/AppKit/CPAlert.j +++ b/AppKit/CPAlert.j @@ -302,11 +302,11 @@ var CPAlertWarningImage, /* @ignore */ - (void)_notifyDelegate:(id)button { - if (_delegate && [_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)]) - [_delegate alertDidEnd:self returnCode:[button tag]]; - [CPApp abortModal]; [_alertPanel close]; + + if (_delegate && [_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)]) + [_delegate alertDidEnd:self returnCode:[button tag]]; } @end diff --git a/AppKit/CPDocument.j b/AppKit/CPDocument.j index 3582a705b..ef87fe151 100644 --- a/AppKit/CPDocument.j +++ b/AppKit/CPDocument.j @@ -282,12 +282,13 @@ var CPDocumentUntitledCount = 0; var view = [viewController view], theWindow = [[CPWindow alloc] initWithContentRect:[view frame] styleMask:CPTitledWindowMask | CPClosableWindowMask | CPMiniaturizableWindowMask | CPResizableWindowMask]; - [theWindow setSupportsMultipleDocuments:YES]; - windowController = [[CPWindowController alloc] initWithWindow:theWindow]; } } + if (windowController && viewController) + [windowController setSupportsMultipleDocuments:YES]; + if (windowController) [self addWindowController:windowController]; @@ -838,7 +839,7 @@ var CPDocumentUntitledCount = 0; - (void)close { - [_windowControllers makeObjectsPerformSelector:@selector(close)]; + [_windowControllers makeObjectsPerformSelector:@selector(removeDocumentAndCloseIfNecessary:) withObject:self]; [[CPDocumentController sharedDocumentController] removeDocument:self]; } @@ -846,6 +847,7 @@ var CPDocumentUntitledCount = 0; { if ([controller shouldCloseDocument] || ([_windowControllers count] < 2 && [_windowControllers indexOfObject:controller] !== CPNotFound)) [self canCloseDocumentWithDelegate:delegate shouldCloseSelector:selector contextInfo:info]; + else if ([delegate respondsToSelector:selector]) objj_msgSend(delegate, selector, self, YES, info); } diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 83fdb8a9f..f82c3da50 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -258,7 +258,6 @@ var CPWindowSaveImage = nil, BOOL _isMovableByWindowBackground; unsigned _shadowStyle; - BOOL _supportsMultipleDocuments; BOOL _isDocumentEdited; BOOL _isDocumentSaving; @@ -460,19 +459,6 @@ CPTexturedBackgroundWindowMask return _CPBorderlessBridgeWindowView; } -- (void)setSupportsMultipleDocuments:(BOOL)shouldSupportMultipleDocuments -{ - shouldSupportMultipleDocuments = !!shouldSupportMultipleDocuments; - - // FIXME: throw exception if window controller already has multiple documents and shouldSupportMultipleDocuments === NO - _supportsMultipleDocuments = shouldSupportMultipleDocuments; -} - -- (BOOL)supportsMultipleDocuments -{ - return _supportsMultipleDocuments; -} - - (void)awakeFromCib { if (_initialFirstResponder) @@ -1650,13 +1636,15 @@ CPTexturedBackgroundWindowMask else if ([self respondsToSelector:@selector(windowShouldClose:)] && ![self windowShouldClose:self]) return; - var document = [_windowController document]; - if (document) + var documents = [_windowController documents]; + if ([documents count]) { - [document shouldCloseWindowController:_windowController - delegate:self - shouldCloseSelector:@selector(_document:shouldClose:contextInfo:) - contextInfo:nil]; + var index = [documents indexOfObject:[_windowController document]]; + + [documents[index] shouldCloseWindowController:_windowController + delegate:self + shouldCloseSelector:@selector(_document:shouldClose:contextInfo:) + contextInfo:index]; } else [self close]; @@ -1665,7 +1653,27 @@ CPTexturedBackgroundWindowMask - (void)_document:(CPDocument)document shouldClose:(BOOL)shouldClose contextInfo:(Object)context { if (shouldClose) - [self close]; + { + var windowController = [self windowController], + documents = [windowController documents]; + + [documents[context] close]; + + var count = [documents count]; + if (count) + { + var index = context % count; + + [windowController setDocument:documents[index]]; + + [documents[index] shouldCloseWindowController:_windowController + delegate:self + shouldCloseSelector:@selector(_document:shouldClose:contextInfo:) + contextInfo:index]; + } + else + [self close]; + } } /*! diff --git a/AppKit/CPWindowController.j b/AppKit/CPWindowController.j index e9e9abe4a..5909e2d63 100644 --- a/AppKit/CPWindowController.j +++ b/AppKit/CPWindowController.j @@ -43,8 +43,10 @@ { CPWindow _window; + CPArray _documents; CPDocument _document; BOOL _shouldCloseDocument; + BOOL _supportsMultipleDocuments; id _cibOwner; CPString _windowCibName; @@ -74,6 +76,8 @@ [self setShouldCloseDocument:NO]; [self setNextResponder:CPApp]; + + _documents = []; } return self; @@ -220,6 +224,9 @@ if (_document) { + if (![self supportsMultipleDocuments]) + [self removeDocument:_document]; + [defaultCenter removeObserver:self name:CPDocumentWillSaveNotification object:_document]; @@ -237,6 +244,8 @@ if (_document) { + [self addDocument:_document]; + [defaultCenter addObserver:self selector:@selector(_documentWillSave:) name:CPDocumentWillSaveNotification @@ -263,6 +272,48 @@ [self synchronizeWindowTitleWithDocumentName]; } +- (void)setSupportsMultipleDocuments:(BOOL)shouldSupportMultipleDocuments +{ + _supportsMultipleDocuments = shouldSupportMultipleDocuments; +} + +- (BOOL)supportsMultipleDocuments +{ + return _supportsMultipleDocuments; +} + +- (void)addDocument:(CPDocument)aDocument +{ + if (aDocument && ![_documents containsObject:aDocument]) + [_documents addObject:aDocument]; +} + +- (void)removeDocument:(CPDocument)aDocument +{ + var index = [_documents indexOfObjectIdenticalTo:aDocument]; + + if (index === CPNotFound) + return; + + [_documents removeObjectAtIndex:index]; + + if (_document === aDocument && [_documents count]) + [self setDocument:[_documents objectAtIndex:MIN(index, [_documents count] - 1)]]; +} + +- (void)removeDocumentAndCloseIfNecessary:(CPDocument)aDocument +{ + [self removeDocument:aDocument]; + + if (![_documents count]) + [self close]; +} + +- (CPArray)documents +{ + return _documents; +} + - (void)setViewController:(CPViewController)aViewController { var containerView = [self viewControllerContainerView] || [[self window] contentView], From b050559532ceef43508b48f9314a1634406ef48b Mon Sep 17 00:00:00 2001 From: Tom Robinson Date: Tue, 27 Oct 2009 17:38:31 -0700 Subject: [PATCH 27/58] Improved capp gen. Don't blow away entire Frameworks directory with --force, just Objj/Foundation/AppKit. --- Tools/capp/Generate.j | 106 +++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 54 deletions(-) diff --git a/Tools/capp/Generate.j b/Tools/capp/Generate.j index d112de349..dc4bfb914 100644 --- a/Tools/capp/Generate.j +++ b/Tools/capp/Generate.j @@ -3,6 +3,9 @@ var File = require("file"); +var FILE = File; +var OBJJ = require("objj/objj"); +var SYSTEM = require("system"); function gen(/*va_args*/) { @@ -58,12 +61,12 @@ function gen(/*va_args*/) config = {}; if (File.isFile(configFile)) config = JSON.parse(File.read(configFile)); - print(config.FrameworksPath) + var destinationProject = new java.io.File(destination), configuration = noConfig ? [Configuration defaultConfiguration] : [Configuration userConfiguration]; if (justFrameworks) - createFrameworksInFile(destinationProject, shouldSymbolicallyLink, force); + createFrameworksInFile(String(destinationProject.getCanonicalPath()), shouldSymbolicallyLink, force); else if (!destinationProject.exists()) { @@ -106,65 +109,60 @@ function gen(/*va_args*/) print("Directory already exists"); } - -function createFrameworksInFile(/*String*/ aFile, /*Boolean*/ shouldSymbolicallyLink, /*Boolean*/ force) +function createFrameworksInFile(/*String*/ aFile, /*Boolean*/ symlink, /*Boolean*/ force) { - if (!File.isDirectory(aFile)) - throw new Error("Can't create Frameworks. Directory does not exist: " + aFile); + var destination = FILE.path(aFile); + + if (!destination.isDirectory()) + throw new Error("Can't create Frameworks. Directory does not exist: " + destination); + + if (symlink && !(SYSTEM.env["CAPP_BUILD"] || SYSTEM.env["STEAM_BUILD"])) + throw "CAPP_BUILD or STEAM_BUILD must be defined"; + + var installedFrameworks = FILE.path(FILE.join(OBJJ.OBJJ_HOME, "lib", "Frameworks")), + builtFrameworks = FILE.path(SYSTEM.env["CAPP_BUILD"] || SYSTEM.env["STEAM_BUILD"]); + + var sourceFrameworks = symlink ? builtFrameworks.join("Release") : installedFrameworks, + sourceDebugFrameworks = symlink ? builtFrameworks.join("Debug") : installedFrameworks.join("Debug"); - var destinationFrameworks = new java.io.File(aFile+ "/Frameworks"), - destinationDebugFrameworks = new java.io.File(aFile + "/Frameworks/Debug"); - - if (destinationFrameworks.exists()) { + var destinationFrameworks = destination.join("Frameworks"), + destinationDebugFrameworks = destination.join("Frameworks", "Debug"); + + print("Creating Frameworks directory in " + destinationFrameworks + "."); + + //destinationFrameworks.mkdirs(); // redundant + destinationDebugFrameworks.mkdirs(); + + ["Objective-J", "Foundation", "AppKit"].forEach(function(framework) { + installFramework( + sourceFrameworks.join(framework), + destinationFrameworks.join(framework), + force, symlink); + installFramework( + sourceDebugFrameworks.join(framework), + destinationDebugFrameworks.join(framework), + force, symlink); + }); +} + +function installFramework(source, dest, force, symlink) { + if (dest.exists()) { if (force) { - print("Updating existing Frameworks directory."); - exec(["rm", "-rf", destinationFrameworks], true); - } - else { - print("Frameworks directory already exists. Use --force to overwrite."); + dest.rmtree(); + } else { + print("Warning: " + dest + " already exists. Use --force to overwrite."); return; } - } else { - print("Creating Frameworks directory in "+destinationFrameworks+"."); } - - if (!shouldSymbolicallyLink) - { - var sourceFrameworks = new java.io.File(OBJJ_HOME + "/lib/Frameworks"); - - exec(["cp", "-R", sourceFrameworks.getCanonicalPath(), destinationFrameworks], true); - - return; + if (source.exists()) { + print((symlink ? "Symlinking " : "Copying ") + source + " to " + dest); + if (symlink) + FILE.symlink(source, dest); + else + FILE.copyTree(source, dest); } - - var BUILD = system.env["CAPP_BUILD"] || system.env["STEAM_BUILD"]; - - if (!BUILD) - throw "CAPP_BUILD or STEAM_BUILD must be defined"; - - // Release Frameworks - new java.io.File(destinationFrameworks).mkdir(); - - exec(["ln", "-s", new java.io.File(BUILD + "/Release/Objective-J").getCanonicalPath(), - new java.io.File(aFile + "/Frameworks/Objective-J").getCanonicalPath()], true); - - exec(["ln", "-s", new java.io.File(BUILD + "/Release/Foundation").getCanonicalPath(), - new java.io.File(aFile + "/Frameworks/Foundation").getCanonicalPath()], true); - - exec(["ln", "-s", new java.io.File(BUILD + "/Release/AppKit").getCanonicalPath(), - new java.io.File(aFile + "/Frameworks/AppKit").getCanonicalPath()], true); - - // Debug Frameworks - new java.io.File(destinationDebugFrameworks).mkdir(); - - exec(["ln", "-s", new java.io.File(BUILD + "/Debug/Objective-J").getCanonicalPath(), - new java.io.File(aFile + "/Frameworks/Debug/Objective-J").getCanonicalPath()], true); - - exec(["ln", "-s", new java.io.File(BUILD + "/Debug/Foundation").getCanonicalPath(), - new java.io.File(aFile + "/Frameworks/Debug/Foundation").getCanonicalPath()], true); - - exec(["ln", "-s", new java.io.File(BUILD + "/Debug/AppKit").getCanonicalPath(), - new java.io.File(aFile + "/Frameworks/Debug/AppKit").getCanonicalPath()], true); + else + print("Warning: "+source+" doesn't exist."); } function toIdentifier(/*String*/ aString) From a0a81be042b06e7bf96948991ea84fc94c49eedc Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Tue, 27 Oct 2009 18:44:09 -0700 Subject: [PATCH 28/58] Add support for reviewing unsaved documents before application termination. --- AppKit/CPApplication.j | 30 +++++++++++++++++++++++++++++- AppKit/CPDocumentController.j | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 76e65a768..c5033ed53 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -39,6 +39,11 @@ CPApp = nil; CPApplicationWillFinishLaunchingNotification = @"CPApplicationWillFinishLaunchingNotification"; CPApplicationDidFinishLaunchingNotification = @"CPApplicationDidFinishLaunchingNotification"; +CPApplicationWillTerminateNotification = @"CPApplicationWillTerminateNotification"; + +CPTerminateNow = YES; +CPTerminateCancel = NO; +CPTerminateLater = -1; // not currently supported CPRunStoppedResponse = -1000; CPRunAbortedResponse = -1001; @@ -295,7 +300,30 @@ CPRunContinuesResponse = -1002; - (void)terminate:(id)aSender { - [CPPlatform terminateApplication]; + [[CPDocumentController sharedDocumentController] closeAllDocumentsWithDelegate:self + didCloseAllSelector:@selector(_documentController:didCloseAll:context:) + contextInfo:nil]; +} + +- (void)_documentController:(NSDocumentController *)docController didCloseAll:(BOOL)didCloseAll context:(Object)info +{ + // callback method for terminate: + if (didCloseAll) + { + if ([_delegate respondsToSelector:@selector(applicationShouldTerminate:)]) + [self replyToApplicationShouldTerminate:[_delegate applicationShouldTerminate:self]]; + else + [self replyToApplicationShouldTerminate:YES]; + } +} + +- (void)replyToApplicationShouldTerminate:(BOOL)terminate +{ + if (terminate == CPTerminateNow) + { + [[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationWillTerminateNotification object:self]; + [CPPlatform terminateApplication]; + } } - (void)activateIgnoringOtherApps:(BOOL)shouldIgnoreOtherApps diff --git a/AppKit/CPDocumentController.j b/AppKit/CPDocumentController.j index 7011c7902..c392d172e 100644 --- a/AppKit/CPDocumentController.j +++ b/AppKit/CPDocumentController.j @@ -323,3 +323,38 @@ var CPSharedDocumentController = nil; } @end + +@implementation CPDocumentController (Closing) + +- (void)closeAllDocumentsWithDelegate:(id)aDelegate didCloseAllSelector:(SEL)didCloseSelector contextInfo:(Object)info +{ + var context = { + delegate: aDelegate, + selector: didCloseSelector, + context: info + }; + + [self _closeDocumentsStartingWith:nil shouldClose:YES context:context]; +} + +// Recursive callback method. Start it by passing in a document of nil. +- (void)_closeDocumentsStartingWith:(CPDocument)aDocument shouldClose:(BOOL)shouldClose context:(Object)context +{ + if (shouldClose) + { + [aDocument close]; + + if ([[self documents] count] > 0) + { + [[[self documents] lastObject] canCloseDocumentWithDelegate:self + shouldCloseSelector:@selector(_closeDocumentsStartingWith:shouldClose:context:) + contextInfo:context]; + return; + } + } + + if ([context.delegate respondsToSelector:context.selector]) + objj_msgSend(context.delegate, context.selector, self, [[self documents] count] === 0, context.context); +} + +@end From 228e801c91dd6f720c25c0d5c88bd9c1c641a634 Mon Sep 17 00:00:00 2001 From: Justin Mecham Date: Tue, 27 Oct 2009 21:23:16 -0400 Subject: [PATCH 29/58] Fixed the class name for archiving CPViewControllers (was CPCollectionView). --- Tools/nib2cib/NSViewController.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/nib2cib/NSViewController.j b/Tools/nib2cib/NSViewController.j index 18fcc5527..58d8fada3 100644 --- a/Tools/nib2cib/NSViewController.j +++ b/Tools/nib2cib/NSViewController.j @@ -43,7 +43,7 @@ - (Class)classForKeyedArchiver { - return [CPCollectionView class]; + return [CPViewController class]; } @end From 25634a66cb2d300fa9d96245ff266488486e63a2 Mon Sep 17 00:00:00 2001 From: Justin Mecham Date: Tue, 27 Oct 2009 21:22:00 -0400 Subject: [PATCH 30/58] Added support to nib2cib for specifying the "Nib Name" property of the View Controller palette to enable view controller initialization from cibs. --- AppKit/CPViewController.j | 15 ++++++++++----- Tools/nib2cib/NSViewController.j | 9 ++++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/AppKit/CPViewController.j b/AppKit/CPViewController.j index a5493b960..63b3c275b 100644 --- a/AppKit/CPViewController.j +++ b/AppKit/CPViewController.j @@ -166,14 +166,15 @@ var CPViewControllerViewKey = @"CPViewControllerViewKey", - CPViewControllerTitleKey = @"CPViewControllerTitleKey"; + CPViewControllerTitleKey = @"CPViewControllerTitleKey", + CPViewControllerCibNameKey = @"CPViewControllerCibNameKey"; @implementation CPViewController (CPCoding) /*! - Initializes the view item by unarchiving data from a coder. + Initializes the view controller by unarchiving data from a coder. @param aCoder the coder from which the data will be unarchived - @return the initialized collection view item + @return the initialized view controller */ - (id)initWithCoder:(CPCoder)aCoder { @@ -183,19 +184,23 @@ var CPViewControllerViewKey = @"CPViewControllerViewKey", { _view = [aCoder decodeObjectForKey:CPViewControllerViewKey]; _title = [aCoder decodeObjectForKey:CPViewControllerTitleKey]; + _cibName = [aCoder decodeObjectForKey:CPViewControllerCibNameKey]; + _cibBundle = [CPBundle mainBundle]; + _cibExternalNameTable = [CPDictionary dictionaryWithObject:self forKey:CPCibOwner]; } return self; } /*! - Archives the colletion view item to the provided coder. - @param aCoder the coder to which the view item should be archived + Archives the view controller to the provided coder. + @param aCoder the coder to which the view controller should be archived */ - (void)encodeWithCoder:(CPCoder)aCoder { [super encodeWithCoder:aCoder]; + [aCoder encodeObject:_cibName forKey:CPViewControllerCibNameKey]; [aCoder encodeObject:_view forKey:CPViewControllerViewKey]; [aCoder encodeObject:_title forKey:CPViewControllerTitleKey]; } diff --git a/Tools/nib2cib/NSViewController.j b/Tools/nib2cib/NSViewController.j index 58d8fada3..9dc3ea5ac 100644 --- a/Tools/nib2cib/NSViewController.j +++ b/Tools/nib2cib/NSViewController.j @@ -27,14 +27,17 @@ - (id)NS_initWithCoder:(CPCoder)aCoder { - return [super NS_initWithCoder:aCoder]; + self = [super NS_initWithCoder:aCoder]; + + if (self) + _cibName = [aCoder decodeObjectForKey:@"NSNibName"]; + + return self; } @end @implementation NSViewController : CPViewController -{ -} - (id)initWithCoder:(CPCoder)aCoder { From d263c74d5def91f27cbaa529515f94afb7d72009 Mon Sep 17 00:00:00 2001 From: Justin Mecham Date: Tue, 27 Oct 2009 22:00:27 -0400 Subject: [PATCH 31/58] Added support for archiving NSTitle and NSNibBundleIdentifier from the View Controller palette for NSViewControllers. --- AppKit/CPViewController.j | 9 ++++++--- Tools/nib2cib/NSViewController.j | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/AppKit/CPViewController.j b/AppKit/CPViewController.j index 63b3c275b..0eebc67a4 100644 --- a/AppKit/CPViewController.j +++ b/AppKit/CPViewController.j @@ -167,7 +167,8 @@ var CPViewControllerViewKey = @"CPViewControllerViewKey", CPViewControllerTitleKey = @"CPViewControllerTitleKey", - CPViewControllerCibNameKey = @"CPViewControllerCibNameKey"; + CPViewControllerCibNameKey = @"CPViewControllerCibNameKey", + CPViewControllerBundleKey = @"CPViewControllerBundleKey"; @implementation CPViewController (CPCoding) @@ -185,7 +186,8 @@ var CPViewControllerViewKey = @"CPViewControllerViewKey", _view = [aCoder decodeObjectForKey:CPViewControllerViewKey]; _title = [aCoder decodeObjectForKey:CPViewControllerTitleKey]; _cibName = [aCoder decodeObjectForKey:CPViewControllerCibNameKey]; - _cibBundle = [CPBundle mainBundle]; + _cibBundle = [aCoder decodeObjectForKey:CPViewControllerBundleKey] || [CPBundle mainBundle]; + _cibExternalNameTable = [CPDictionary dictionaryWithObject:self forKey:CPCibOwner]; } @@ -200,9 +202,10 @@ var CPViewControllerViewKey = @"CPViewControllerViewKey", { [super encodeWithCoder:aCoder]; - [aCoder encodeObject:_cibName forKey:CPViewControllerCibNameKey]; [aCoder encodeObject:_view forKey:CPViewControllerViewKey]; [aCoder encodeObject:_title forKey:CPViewControllerTitleKey]; + [aCoder encodeObject:_cibName forKey:CPViewControllerCibNameKey]; + [aCoder encodeObject:_cibBundle forKey:CPViewControllerBundleKey]; } @end diff --git a/Tools/nib2cib/NSViewController.j b/Tools/nib2cib/NSViewController.j index 9dc3ea5ac..7284a124a 100644 --- a/Tools/nib2cib/NSViewController.j +++ b/Tools/nib2cib/NSViewController.j @@ -30,7 +30,11 @@ self = [super NS_initWithCoder:aCoder]; if (self) + { + _title = [aCoder decodeObjectForKey:@"NSTitle"]; _cibName = [aCoder decodeObjectForKey:@"NSNibName"]; + _cibBundle = [aCoder decodeObjectForKey:@"NSNibBundleIdentifier"]; + } return self; } From 42611f3a8431956ee226a4c18967efd6891c3176 Mon Sep 17 00:00:00 2001 From: Tom Robinson Date: Wed, 28 Oct 2009 00:07:23 -0700 Subject: [PATCH 32/58] Missing GET_FILE import. --- Objective-J/Tools/objj/lib-js/objj/objjc.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Objective-J/Tools/objj/lib-js/objj/objjc.js b/Objective-J/Tools/objj/lib-js/objj/objjc.js index 553d60e7a..461d2c3a3 100644 --- a/Objective-J/Tools/objj/lib-js/objj/objjc.js +++ b/Objective-J/Tools/objj/lib-js/objj/objjc.js @@ -3,8 +3,9 @@ var FILE = require("file"), objj = require("./objj"), objj_preprocess = objj.objj_preprocess, IS_FILE = objj.IS_FILE, - GET_CODE = objj.GET_CODE, IS_LOCAL = objj.IS_LOCAL, + GET_CODE = objj.GET_CODE, + GET_FILE = objj.GET_FILE, MARKER_IMPORT_STD = objj.MARKER_IMPORT_STD, MARKER_IMPORT_LOCAL = objj.MARKER_IMPORT_LOCAL, MARKER_CODE = objj.MARKER_CODE, From 22c248454ef0bba9595d72a0a147cc23cbee6899 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 28 Oct 2009 00:11:42 -0700 Subject: [PATCH 33/58] Fix for the fact that bundles are not encodable in the last commits. --- AppKit/CPViewController.j | 6 ++++-- Tools/nib2cib/NSViewController.j | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/AppKit/CPViewController.j b/AppKit/CPViewController.j index 0eebc67a4..7aa31ec85 100644 --- a/AppKit/CPViewController.j +++ b/AppKit/CPViewController.j @@ -186,7 +186,9 @@ var CPViewControllerViewKey = @"CPViewControllerViewKey", _view = [aCoder decodeObjectForKey:CPViewControllerViewKey]; _title = [aCoder decodeObjectForKey:CPViewControllerTitleKey]; _cibName = [aCoder decodeObjectForKey:CPViewControllerCibNameKey]; - _cibBundle = [aCoder decodeObjectForKey:CPViewControllerBundleKey] || [CPBundle mainBundle]; + + var bundlePath = [aCoder decodeObjectForKey:CPViewControllerBundleKey]; + _cibBundle = bundlePath ? [CPBundle bundleWithPath:bundlePath] : [CPBundle mainBundle]; _cibExternalNameTable = [CPDictionary dictionaryWithObject:self forKey:CPCibOwner]; } @@ -205,7 +207,7 @@ var CPViewControllerViewKey = @"CPViewControllerViewKey", [aCoder encodeObject:_view forKey:CPViewControllerViewKey]; [aCoder encodeObject:_title forKey:CPViewControllerTitleKey]; [aCoder encodeObject:_cibName forKey:CPViewControllerCibNameKey]; - [aCoder encodeObject:_cibBundle forKey:CPViewControllerBundleKey]; + [aCoder encodeObject:[_cibBundle bundlePath] forKey:CPViewControllerBundleKey]; } @end diff --git a/Tools/nib2cib/NSViewController.j b/Tools/nib2cib/NSViewController.j index 7284a124a..a0e522a7a 100644 --- a/Tools/nib2cib/NSViewController.j +++ b/Tools/nib2cib/NSViewController.j @@ -33,7 +33,7 @@ { _title = [aCoder decodeObjectForKey:@"NSTitle"]; _cibName = [aCoder decodeObjectForKey:@"NSNibName"]; - _cibBundle = [aCoder decodeObjectForKey:@"NSNibBundleIdentifier"]; + _cibBundle = [CPBundle bundleWithPath:[aCoder decodeObjectForKey:@"NSNibBundleIdentifier"]]; } return self; From ba84e6d3e26d7a4be222fe7fe42cdb6bef3dfa3b Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 28 Oct 2009 00:12:03 -0700 Subject: [PATCH 34/58] Support for sendsActionOnEndEditing in CPControl. Only works for textfields right now. --- AppKit/CPControl.j | 3 ++- AppKit/CPTextField.j | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/AppKit/CPControl.j b/AppKit/CPControl.j index d00f3aa6f..f9ddc817e 100644 --- a/AppKit/CPControl.j +++ b/AppKit/CPControl.j @@ -94,7 +94,8 @@ var CPControlBlackColor = [CPColor blackColor]; id _target; SEL _action; int _sendActionOn; - + BOOL _sendsActionOnEndEditing @accessors(property=sendsActionOnEndEditing); + // Mouse Tracking Support BOOL _continuousTracking; BOOL _trackingWasWithinFrame; diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index ebf0815c9..1b253d44c 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -269,8 +269,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); if (aDOMEvent && aDOMEvent.keyCode == CPReturnKeyCode) { - [owner sendAction:[owner action] to:[owner target]]; - [[owner window] makeFirstResponder:nil]; + [owner sendAction:[owner action] to:[owner target]]; + [owner selectText:nil]; } else if (aDOMEvent && aDOMEvent.keyCode == CPTabKeyCode) { @@ -666,6 +666,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); //post CPControlTextDidEndEditingNotification [self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]]; + if ([self sendsActionOnEndEditing]) + [self sendAction:[self action] to:[self target]]; + return YES; } From eaf701beca5adce15a6863507cdddaf693e54606 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 28 Oct 2009 16:24:41 -0700 Subject: [PATCH 35/58] Support key paths instead of simple keys in sort descriptors. Match Cocoa's behavior here. --- Foundation/CPSortDescriptor.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Foundation/CPSortDescriptor.j b/Foundation/CPSortDescriptor.j index 415e0b01a..c7b78c840 100755 --- a/Foundation/CPSortDescriptor.j +++ b/Foundation/CPSortDescriptor.j @@ -136,7 +136,7 @@ CPOrderedDescending = 1; */ - (CPComparisonResult)compareObject:(id)lhsObject withObject:(id)rhsObject { - return (_ascending ? 1 : -1) * [[lhsObject valueForKey:_key] performSelector:_selector withObject:[rhsObject valueForKey:_key]]; + return (_ascending ? 1 : -1) * [[lhsObject valueForKeyPath:_key] performSelector:_selector withObject:[rhsObject valueForKeyPath:_key]]; } /*! From 4248348308cb02ee6b6a3a66246133ab35c52072 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 28 Oct 2009 20:01:00 -0700 Subject: [PATCH 36/58] Updates to the way notifications work. New notifications for focus/blur. --- AppKit/CPTextField.j | 104 ++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 41 deletions(-) diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 1b253d44c..74b094c34 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -30,50 +30,18 @@ #include "Platform/DOM/CPDOMDisplayServer.h" -/* - @global - @group CPLineBreakMode -*/ CPLineBreakByWordWrapping = 0; -/* - @global - @group CPLineBreakMode -*/ CPLineBreakByCharWrapping = 1; -/* - @global - @group CPLineBreakMode -*/ CPLineBreakByClipping = 2; -/* - @global - @group CPLineBreakMode -*/ CPLineBreakByTruncatingHead = 3; -/* - @global - @group CPLineBreakMode -*/ CPLineBreakByTruncatingTail = 4; -/* - @global - @group CPLineBreakMode -*/ CPLineBreakByTruncatingMiddle = 5; -/* - A textfield bezel with a squared corners. - @global - @group CPTextFieldBezelStyle -*/ -CPTextFieldSquareBezel = 0; -/* - A textfield bezel with rounded corners. - @global - @group CPTextFieldBezelStyle -*/ -CPTextFieldRoundedBezel = 1; +CPTextFieldSquareBezel = 0; /*! A textfield bezel with a squared corners. */ +CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */ +CPTextFieldDidFocusNotification = @"CPTextFieldDidFocusNotification"; +CPTextFieldDidBlurNotification = @"CPTextFieldDidBlurNotification"; #if PLATFORM(DOM) @@ -118,6 +86,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); */ @implementation CPTextField : CPControl { + BOOL _isEditing; + BOOL _isEditable; BOOL _isSelectable; BOOL _isSecure; @@ -269,6 +239,12 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); if (aDOMEvent && aDOMEvent.keyCode == CPReturnKeyCode) { + if (owner._isEditing) + { + owner._isEditing = NO; + [owner textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:owner userInfo:nil]]; + } + [owner sendAction:[owner action] to:[owner target]]; [owner selectText:nil]; } @@ -290,6 +266,12 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); if ([CPTextFieldInputOwner stringValue] !== CPTextFieldTextDidChangeValue) { + if (!CPTextFieldInputOwner._isEditing) + { + CPTextFieldInputOwner._isEditing = YES; + [CPTextFieldInputOwner textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:CPTextFieldInputOwner userInfo:nil]]; + } + [CPTextFieldInputOwner textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:CPTextFieldInputOwner userInfo:nil]]; CPTextFieldTextDidChangeValue = [CPTextFieldInputOwner stringValue]; } @@ -567,6 +549,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); [self setNeedsLayout]; + _isEditing = NO; + #if PLATFORM(DOM) var string = [self stringValue], @@ -601,8 +585,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); CPTextFieldInputOwner = self; }, 0.0); - //post CPControlTextDidBeginEditingNotification - [self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]]; element.value = [self stringValue]; [[[self window] platformWindow] _propagateCurrentDOMEvent:YES]; @@ -618,6 +600,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); document.body.onselectstart = function () {}; } + [self textDidFocus:[CPNotification notificationWithName:CPTextFieldDidFocusNotification object:self userInfo:nil]]; #endif return YES; @@ -664,14 +647,38 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); #endif //post CPControlTextDidEndEditingNotification - [self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]]; + if (_isEditing) + { + _isEditing = NO; + [self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]]; - if ([self sendsActionOnEndEditing]) - [self sendAction:[self action] to:[self target]]; + if ([self sendsActionOnEndEditing]) + [self sendAction:[self action] to:[self target]]; + } + + [self textDidBlur:[CPNotification notificationWithName:CPTextFieldDidBlurNotification object:self userInfo:nil]]; return YES; } +- (void)textDidBlur:(CPNotification)note +{ + //this looks to prevent false propagation of notifications for other objects + if([note object] != self) + return; + + [[CPNotificationCenter defaultCenter] postNotification:note]; +} + +- (void)textDidFocus:(CPNotification)note +{ + //this looks to prevent false propagation of notifications for other objects + if([note object] != self) + return; + + [[CPNotificationCenter defaultCenter] postNotification:note]; +} + - (void)mouseDown:(CPEvent)anEvent { // Don't track! (ever?) @@ -811,6 +818,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); [defaultCenter removeObserver:_delegate name:CPControlTextDidBeginEditingNotification object:self]; [defaultCenter removeObserver:_delegate name:CPControlTextDidChangeNotification object:self]; [defaultCenter removeObserver:_delegate name:CPControlTextDidEndEditingNotification object:self]; + [defaultCenter removeObserver:_delegate name:CPTextFieldDidFocusNotification object:self]; + [defaultCenter removeObserver:_delegate name:CPTextFieldDidBlurNotification object:self]; } _delegate = aDelegate; @@ -837,6 +846,19 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); name:CPControlTextDidEndEditingNotification object:self]; + if ([_delegate respondsToSelector:@selector(controlTextDidFocus:)]) + [defaultCenter + addObserver:_delegate + selector:@selector(controlTextDidFocus:) + name:CPTextFieldDidFocusNotification + object:self]; + + if ([_delegate respondsToSelector:@selector(controlTextDidBlur:)]) + [defaultCenter + addObserver:_delegate + selector:@selector(controlTextDidBlur:) + name:CPTextFieldDidBlurNotification + object:self]; } - (id)delegate From 9f2ea190fcd9000729632d84b285312a05a6acbc Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 28 Oct 2009 20:20:33 -0700 Subject: [PATCH 37/58] Make text field KVO compliant again. --- AppKit/CPTextField.j | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 74b094c34..7c748dcd9 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -701,8 +701,10 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); */ - (void)_setStringValue:(id)aValue { + [self willChangeValueForKey:@"objectValue"]; [super setObjectValue:String(aValue)]; [self _updatePlaceholderState]; + [self didChangeValueForKey:@"objectValue"]; } - (void)setObjectValue:(id)aValue From 4ca0044bbd4622c0c39fe9fa6d0f9bcff685e227 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 28 Oct 2009 23:38:58 -0700 Subject: [PATCH 38/58] Add isEqual: to CPDate --- Foundation/CPDate.j | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Foundation/CPDate.j b/Foundation/CPDate.j index 436c51a0c..3d712734c 100644 --- a/Foundation/CPDate.j +++ b/Foundation/CPDate.j @@ -127,6 +127,11 @@ var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0)); return [[CPDate date] timeIntervalSinceReferenceDate]; } +- (BOOL)isEqual:(CPDate)aDate +{ + return [self isEqualToDate:aDate]; +} + - (BOOL)isEqualToDate:(CPDate)anotherDate { return !(self < anotherDate || self > anotherDate); From c48d9a01c6a50fdf63c1b80fab6a80a9df138197 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Thu, 29 Oct 2009 00:53:13 -0700 Subject: [PATCH 39/58] Removed some remaining cell "influences" in nib2cib'ed cib. There are references to NSCells in the object graph which should be removed, their children promoted to their parent's children. Reviewed by me. --- Tools/nib2cib/NSCell.j | 1 + Tools/nib2cib/NSIBObjectData.j | 64 ++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/Tools/nib2cib/NSCell.j b/Tools/nib2cib/NSCell.j index a25a3f25f..604afeadf 100644 --- a/Tools/nib2cib/NSCell.j +++ b/Tools/nib2cib/NSCell.j @@ -27,6 +27,7 @@ @import "NSFont.j" + @implementation NSCell : CPObject { int _state @accessors(readonly, getter=state); diff --git a/Tools/nib2cib/NSIBObjectData.j b/Tools/nib2cib/NSIBObjectData.j index 6c7214bbb..e19f4ce78 100644 --- a/Tools/nib2cib/NSIBObjectData.j +++ b/Tools/nib2cib/NSIBObjectData.j @@ -58,6 +58,8 @@ _objectsKeys = [aCoder decodeObjectForKey:@"NSObjectsKeys"]; _objectsValues = [aCoder decodeObjectForKey:@"NSObjectsValues"]; + [self removeCellsFromObjectGraph]; + //_oidKeys = [aCoder decodeObjectForKey:@"NSOidsKeys"]; //_oidValues = [aCoder decodeObjectForKey:@"NSOidsValues"]; @@ -68,6 +70,68 @@ return self; } +- (void)removeCellsFromObjectGraph +{ + // FIXME: Remove from top level objects and connections? + + // Most cell references should be naturally removed by the fact that we don't manually + // encode them anywhere, however, they remain in our object graph. For each cell found, + // take its children and promote them to our parent object's children. + var count = _objectsKeys.length, + parentForCellUIDs = { }, + promotedChildrenForCellUIDs = { }; + + while (count--) + { + var child = _objectsKeys[count]; + + if (!child) + continue; + + var parent = _objectsValues[count]; + + // If this object is a cell, remember it's parent. + if ([child isKindOfClass:[NSCell class]]) + { + parentForCellUIDs[[child UID]] = parent; + continue; + } + + // If parent also isn't a cell, we don't care about it. + if (![parent isKindOfClass:[NSCell class]]) + continue; + + // Remember this child for later promotion. + var parentUID = [parent UID], + children = promotedChildrenForCellUIDs[parentUID]; + + if (!children) + { + children = []; + promotedChildrenForCellUIDs[parentUID] = children; + } + + children.push(child); + + _objectsKeys.splice(count, 1); + _objectsValues.splice(count, 1); + } + + for (var cellUID in promotedChildrenForCellUIDs) + if (promotedChildrenForCellUIDs.hasOwnProperty(cellUID)) + { + var children = promotedChildrenForCellUIDs[cellUID], + parent = parentForCellUIDs[cellUID]; + + children.forEach(function(aChild) + { + CPLog.warn("Promoted " + aChild + " to child of " + parent); + _objectsKeys.push(aChild); + _objectsValues.push(parent); + }); + } +} + @end @implementation NSIBObjectData : _CPCibObjectData From 8da4ea08236fd38a14851352535e4f5a9beaae04 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Thu, 29 Oct 2009 16:25:05 -0700 Subject: [PATCH 40/58] Added import just in case. Reviewed by me. --- Tools/nib2cib/NSIBObjectData.j | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tools/nib2cib/NSIBObjectData.j b/Tools/nib2cib/NSIBObjectData.j index e19f4ce78..26d2e5481 100644 --- a/Tools/nib2cib/NSIBObjectData.j +++ b/Tools/nib2cib/NSIBObjectData.j @@ -22,6 +22,8 @@ @import +@import "NSCell.j" + @implementation _CPCibObjectData (NSCoding) From 04235464513d752953f213feaa35756e300ab3cb Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Thu, 29 Oct 2009 16:33:56 -0700 Subject: [PATCH 41/58] Update to the new close/warn stuff to correctly support multiple windows per document and multiple documents per window. --- AppKit/CPDocument.j | 24 +++++++++++++++++++++++- AppKit/CPWindow/CPWindow.j | 26 +++++++++++++------------- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/AppKit/CPDocument.j b/AppKit/CPDocument.j index ef87fe151..22f62b0a8 100644 --- a/AppKit/CPDocument.j +++ b/AppKit/CPDocument.j @@ -317,6 +317,20 @@ var CPDocumentUntitledCount = 0; [aWindowController setDocument:self]; } +/*! + Remove a controller to the document's list of controllers. This should + be called after closing the controller's window. + @param aWindowController the controller to remove +*/ +- (void)removeWindowController:(CPWindowController)aWindowController +{ + if (aWindowController) + [_windowControllers removeObject:aWindowController]; + + if ([aWindowController document] === self) + [aWindowController setDocument:nil]; +} + - (CPView)view { return _view; @@ -846,12 +860,20 @@ var CPDocumentUntitledCount = 0; - (void)shouldCloseWindowController:(CPWindowController)controller delegate:(id)delegate shouldCloseSelector:(SEL)selector contextInfo:(Object)info { if ([controller shouldCloseDocument] || ([_windowControllers count] < 2 && [_windowControllers indexOfObject:controller] !== CPNotFound)) - [self canCloseDocumentWithDelegate:delegate shouldCloseSelector:selector contextInfo:info]; + [self canCloseDocumentWithDelegate:self shouldCloseSelector:@selector(_document:shouldClose:context:) contextInfo:{delegate:delegate, selector:selector, context:info}]; else if ([delegate respondsToSelector:selector]) objj_msgSend(delegate, selector, self, YES, info); } +- (void)_document:(CPDocument)aDocument shouldClose:(BOOL)shouldClose context:(Object)context +{ + if (aDocument === self && shouldClose) + [self close]; + + objj_msgSend(context.delegate, context.selector, aDocument, shouldClose, context.context); +} + - (void)canCloseDocumentWithDelegate:(id)aDelegate shouldCloseSelector:(SEL)aSelector contextInfo:(Object)context { if (![self isDocumentEdited]) diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index f82c3da50..59c0c3501 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1643,33 +1643,33 @@ CPTexturedBackgroundWindowMask [documents[index] shouldCloseWindowController:_windowController delegate:self - shouldCloseSelector:@selector(_document:shouldClose:contextInfo:) - contextInfo:index]; + shouldCloseSelector:@selector(_windowControllerContainingDocument:shouldClose:contextInfo:) + contextInfo:{documents:[documents copy], visited:0, index:index}]; } else [self close]; } -- (void)_document:(CPDocument)document shouldClose:(BOOL)shouldClose contextInfo:(Object)context +- (void)_windowControllerContainingDocument:(CPDocument)document shouldClose:(BOOL)shouldClose contextInfo:(Object)context { if (shouldClose) { var windowController = [self windowController], - documents = [windowController documents]; + documents = context.documents, + count = [documents count], + visited = ++context.visited, + index = ++context.index % count; - [documents[context] close]; + [document removeWindowController:windowController]; - var count = [documents count]; - if (count) + if (visited < count) { - var index = context % count; - [windowController setDocument:documents[index]]; [documents[index] shouldCloseWindowController:_windowController delegate:self - shouldCloseSelector:@selector(_document:shouldClose:contextInfo:) - contextInfo:index]; + shouldCloseSelector:@selector(_windowControllerContainingDocument:shouldClose:contextInfo:) + contextInfo:context]; } else [self close]; @@ -1682,9 +1682,9 @@ CPTexturedBackgroundWindowMask */ - (void)close { - [[CPNotificationCenter defaultCenter] postNotificationName:CPWindowWillCloseNotification object:self]; + [[CPNotificationCenter defaultCenter] postNotificationName:CPWindowWillCloseNotification object:self]; - [self orderOut:nil]; + [self orderOut:nil]; } // Managing Main Status From 2e26db5bf59506658778e928364417394c709206 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Thu, 29 Oct 2009 21:17:12 -0700 Subject: [PATCH 42/58] Add mixed states to checkboxes. --- .../check-box-bezel-mixed-disabled.png | Bin 0 -> 424 bytes .../check-box-bezel-mixed-highlighted.png | Bin 0 -> 419 bytes .../Resources/check-box-bezel-mixed.png | Bin 0 -> 420 bytes AppKit/Themes/Aristo/ThemeDescriptors.j | 35 ++++++++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 AppKit/Themes/Aristo/Resources/check-box-bezel-mixed-disabled.png create mode 100644 AppKit/Themes/Aristo/Resources/check-box-bezel-mixed-highlighted.png create mode 100644 AppKit/Themes/Aristo/Resources/check-box-bezel-mixed.png diff --git a/AppKit/Themes/Aristo/Resources/check-box-bezel-mixed-disabled.png b/AppKit/Themes/Aristo/Resources/check-box-bezel-mixed-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..2caf2010e94384053bb1ac0059ca88a23a650a73 GIT binary patch literal 424 zcmV;Z0ayNsP)wEiUIFm7E=GI_@C*_|n{adTr|h z5i5(i9JCw&_2rKLR9yqkKRlZimW>aW=T;NVi3C@$Clo4R;x2XsDg{!-m)R3aAxMeA zgZkw~-fEc{O^b&4N((E+?&fy+Eodf>a6Ms5p9wK=-Kw&`c~;z4w@y& zG6*?_*&hj4^ZaE|ljT?_Q^%<41+QKFa5Pf+|x+!Cih0t^6rDc*n} S{u$N)0000fs-{6&Ym_$oC(dl6J>-z210PwI@0V|9 zc8xSmVbWsfSJw`Hk5PN5dI_eDYN5`UQtEVVaqghGG!L%L3dsQ%^{23V_}uAPOiH=$ zO*wG?)&(wPA#5`XYMukc5$uP(xOAWBhruwRug`=OdZTI)$D|N?QMHI;0{i4#>5Z4i zJNW#Fz%Y!QnXc4dZa}cw93>-%@HqM5_6EY&Hkej^>XIk0u^Gd{N+W}HGS>?#Z>9#p z`YhP4mxG5tF*xq@zn8dCa&|>q+dIXB%Dm#QXEDjNsb?w2$(5!pb+U-KNPN>YON02N z>DZBp59FfXk0D9u1gcQvBR_I2CY3yizrP&RF8(wq5&Vw2L>>JKFaQ*I+p=II;CTQ5 N002ovPDHLkV1maEx_4r2yQwE7CTflZAx(v)Fi$4B%YHP9V#a2z5E0Y z|Cj&%H_^f{glU&JySz5(c|_VHRWmR)sZBZ+K@gm*)~x-t Date: Thu, 29 Oct 2009 22:22:27 -0700 Subject: [PATCH 43/58] Add disabled states for all the existing controls. --- .../button-bezel-disabled-center.png | Bin 131 -> 148 bytes .../Resources/button-bezel-disabled-left.png | Bin 211 -> 221 bytes .../Resources/button-bezel-disabled-right.png | Bin 202 -> 217 bytes .../Resources/check-box-bezel-disabled.png | Bin 296 -> 283 bytes .../check-box-bezel-selected-disabled.png | Bin 598 -> 639 bytes .../default-button-bezel-disabled-center.png | Bin 0 -> 158 bytes .../default-button-bezel-disabled-left.png | Bin 0 -> 260 bytes .../default-button-bezel-disabled-right.png | Bin 0 -> 261 bytes .../horizontal-track-disabled-center.png | Bin 0 -> 130 bytes .../horizontal-track-disabled-left.png | Bin 0 -> 182 bytes .../horizontal-track-disabled-right.png | Bin 0 -> 185 bytes .../Themes/Aristo/Resources/knob-disabled.png | Bin 0 -> 874 bytes .../popup-bezel-disabled-right-pullsdown.png | Bin 0 -> 471 bytes .../Resources/popup-bezel-disabled-right.png | Bin 0 -> 614 bytes .../Aristo/Resources/radio-bezel-disabled.png | Bin 640 -> 653 bytes .../radio-bezel-selected-disabled.png | Bin 799 -> 841 bytes ...roller-horizontal-knob-disabled-center.png | Bin 0 -> 154 bytes ...scroller-horizontal-knob-disabled-left.png | Bin 0 -> 436 bytes ...croller-horizontal-knob-disabled-right.png | Bin 0 -> 452 bytes ...scroller-vertical-knob-disabled-bottom.png | Bin 0 -> 421 bytes ...scroller-vertical-knob-disabled-center.png | Bin 0 -> 143 bytes .../scroller-vertical-knob-disabled-top.png | Bin 0 -> 424 bytes ...egmented-control-bezel-disabled-center.png | Bin 0 -> 146 bytes ...gmented-control-bezel-disabled-divider.png | Bin 0 -> 135 bytes .../segmented-control-bezel-disabled-left.png | Bin 0 -> 220 bytes ...segmented-control-bezel-disabled-right.png | Bin 0 -> 215 bytes ...trol-bezel-highlighted-disabled-center.png | Bin 0 -> 157 bytes ...rol-bezel-highlighted-disabled-divider.png | Bin 0 -> 144 bytes ...ontrol-bezel-highlighted-disabled-left.png | Bin 0 -> 259 bytes ...ntrol-bezel-highlighted-disabled-right.png | Bin 0 -> 261 bytes ...egmented-control-bezel-inactive-center.png | Bin 140 -> 0 bytes ...gmented-control-bezel-inactive-divider.png | Bin 133 -> 0 bytes .../segmented-control-bezel-inactive-left.png | Bin 228 -> 0 bytes ...segmented-control-bezel-inactive-right.png | Bin 228 -> 0 bytes .../slider-circular-disabled-bezel.png | Bin 0 -> 1154 bytes .../slider-circular-disabled-knob.png | Bin 0 -> 198 bytes .../vertical-track-disabled-bottom.png | Bin 0 -> 170 bytes .../vertical-track-disabled-center.png | Bin 0 -> 126 bytes .../Resources/vertical-track-disabled-top.png | Bin 0 -> 199 bytes AppKit/Themes/Aristo/ThemeDescriptors.j | 119 +++++++++++++++--- 40 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 AppKit/Themes/Aristo/Resources/default-button-bezel-disabled-center.png create mode 100644 AppKit/Themes/Aristo/Resources/default-button-bezel-disabled-left.png create mode 100644 AppKit/Themes/Aristo/Resources/default-button-bezel-disabled-right.png create mode 100644 AppKit/Themes/Aristo/Resources/horizontal-track-disabled-center.png create mode 100644 AppKit/Themes/Aristo/Resources/horizontal-track-disabled-left.png create mode 100644 AppKit/Themes/Aristo/Resources/horizontal-track-disabled-right.png create mode 100644 AppKit/Themes/Aristo/Resources/knob-disabled.png create mode 100644 AppKit/Themes/Aristo/Resources/popup-bezel-disabled-right-pullsdown.png create mode 100644 AppKit/Themes/Aristo/Resources/popup-bezel-disabled-right.png create mode 100644 AppKit/Themes/Aristo/Resources/scroller-horizontal-knob-disabled-center.png create mode 100644 AppKit/Themes/Aristo/Resources/scroller-horizontal-knob-disabled-left.png create mode 100644 AppKit/Themes/Aristo/Resources/scroller-horizontal-knob-disabled-right.png create mode 100644 AppKit/Themes/Aristo/Resources/scroller-vertical-knob-disabled-bottom.png create mode 100644 AppKit/Themes/Aristo/Resources/scroller-vertical-knob-disabled-center.png create mode 100644 AppKit/Themes/Aristo/Resources/scroller-vertical-knob-disabled-top.png create mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-disabled-center.png create mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-disabled-divider.png create mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-disabled-left.png create mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-disabled-right.png create mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-highlighted-disabled-center.png create mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-highlighted-disabled-divider.png create mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-highlighted-disabled-left.png create mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-highlighted-disabled-right.png delete mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-inactive-center.png delete mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-inactive-divider.png delete mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-inactive-left.png delete mode 100644 AppKit/Themes/Aristo/Resources/segmented-control-bezel-inactive-right.png create mode 100644 AppKit/Themes/Aristo/Resources/slider-circular-disabled-bezel.png create mode 100644 AppKit/Themes/Aristo/Resources/slider-circular-disabled-knob.png create mode 100644 AppKit/Themes/Aristo/Resources/vertical-track-disabled-bottom.png create mode 100644 AppKit/Themes/Aristo/Resources/vertical-track-disabled-center.png create mode 100644 AppKit/Themes/Aristo/Resources/vertical-track-disabled-top.png diff --git a/AppKit/Themes/Aristo/Resources/button-bezel-disabled-center.png b/AppKit/Themes/Aristo/Resources/button-bezel-disabled-center.png index 2f25f525283ff733a1593882ccea06a1ee43bc02..310e7382bb5cfae33823f0e4327bd439baf641b2 100644 GIT binary patch delta 94 zcmV-k0HObb0h9rd83+ad002A8m)embC`&d;L_t(|+G5zdckfJw@87@AWcv2)8w1n7 zfBzVm{{R0EWuXy&|Nh0p#VLkn=!FXx7ytqc00n7BQk4r@>i_@%07*qoM6N<$g0&DR AQvd(} delta 77 zcmV-T0J8s-0fPaM83+OZ006YE0F99$C^{ucL_t(|+G4tQ?;gYN-@lna`2YX^1o6Lr j|AJyL_t(|+G5fi$iFckp0^`4|?3M-QU0000< KMNUMnLSTaAYe(Jy delta 146 zcmV;D0B!%>0n-7HNq==oL_t(|+RTo-4Fe$%L>F#Dg3IWF)NQ#E+XWr1@JR^~0f^7~ zu!L)1qzUFt^0?OeaL&EF_hgJAu-3jq2$XZCS}P%A>?wqRF~+ahS_2}26`W%iFb#JT zr95Jc@D*SHz=f)|$vyv{01E&B07*qoM6N<$f+2W7 AasU7T diff --git a/AppKit/Themes/Aristo/Resources/button-bezel-disabled-right.png b/AppKit/Themes/Aristo/Resources/button-bezel-disabled-right.png index 92127238afebd7d57e158ce012f798af02fd27b4..1a986e2fb1a0f86ec935087d77df6006fb68f7c1 100644 GIT binary patch delta 152 zcmV;J0B8To0oehNNq>7uL_t(|+G58o)MsIO{Z* delta 137 zcmV;40CxY`0m=c8Nq=lfL_t(|+RTtU4uBvKM2E24SkEExRvZFqLP-J*pB17O7S_7e zzLzN`Bb;+Ar35o?*4kB+Qn9ZEJ#GB rm@o#$7+aI~9!jYRyD?@t1Q-D1v!!ISH+lU40000c^+`rbx9n@)V3`(O*1GfrAX@2G)>rhAELqJeZ`Yxno}c-vs{*ae=mzTXKeBQ zIQG)lepOW!GV`Q;#S8FLE=5rg8qjBoZ%Ccg!@EiHsVqwdYcySr2!4V)IKBlK0FvRk U5B(X`NdN!<07*qoM6N<$f+#&?lmGw# delta 231 zcmVoL_t(|+QgDE4uUWgh9C6708s;S0>S~<9F2n;C-MMZh?Qu( z0ZG?}6A%(@m=N$iFMutBfAY6ozJ6`;oT{n>034|~bqmXRQETc0g%IZ~%PvWhfb(wry*r)YXwv-qJKZfnl1axufs$*l(<}iw)r`CEGhT%^aFxdA!Fo$JX?u(*$cU=d=Ff78J=Rq9D hz?@?_n%{f`7ywTLewNY=C@KH|002ovPDHLkV1f#|XZ!#F diff --git a/AppKit/Themes/Aristo/Resources/check-box-bezel-selected-disabled.png b/AppKit/Themes/Aristo/Resources/check-box-bezel-selected-disabled.png index fea5c786c0a9dda267d9068b3efa34b05493286d..191c479a9f1e281b42f7a66f577a3dee1cfb067b 100644 GIT binary patch delta 578 zcmV-I0=@m#1pfq(NPhw$NklE zNNcfp0soP2Dkua&&8uWwn zu-|-V&Uc2hEv9MWf65o`_qDW=^CqLW$)!iH3GYpDjB>O$BY!eRp&n1r&8;m`D;1r@ zFpSfOdpalk!y$NF`Zb@N|%bh z-fqMO;sFOI%X!U&R-<5)HN?u7&vw3FcyUxiCBHXb5OpPt~0E! zuHpUsJf^Q+gr@0MFY{ssA3iO>d%%x?zXPMml+_myJWjS1e*IjB+!@A3zKDl+Z{q7x z4l~c5K-K{kJr+f|QpLNuIe-Vx;dJ82p+5BVs@pR=WJ}rJzg`3J1j^+KmcA`R z@wzcMG_vb_hs;1kTO1Xq+EN=NUC~X*3v360@s&XqKyADTEW41zr3^4n_ ziXvgzwL6t%RJqr>g=P?QVxIG62{YK!jUV3$$1uNC`G>!7?vkyafqfM7C($^*C!}&NB1$O{gd-7hm47jY(Hjzu)2{qlx}r53R3TpmXyegrL4uNAe~n6(zjmo;C8WhnveQ zXm>i;2?7MY9P^~VUI6pyFN}f9OtJlHfF-qkM6pm;8uO&QU7{-uu&P-k6tS#u9 zohY28n($0!(HDn<1Ly?WsV+qlm&9w{E5dC0NQM#Z?{@F#r<%X)OX|-vV7B#|*|~>* b1Q-D09uiw;Nr?~700000NkvXXu0mjfxu*jm diff --git a/AppKit/Themes/Aristo/Resources/default-button-bezel-disabled-center.png b/AppKit/Themes/Aristo/Resources/default-button-bezel-disabled-center.png new file mode 100644 index 0000000000000000000000000000000000000000..20cb138e34713b3440506cba4c24a06628284903 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{G!3HF)&rH7sq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6*+jiIEGZ*N_ugtAV=-+UH<*)Mt6UH=x%&@fB%1lNAk>< z;{_NK|FRbUKNR5+({dwz1)s^$47bMK{Z;Q&m>n7z8O}+&otS*Ac>&NY22WQ%mvv4F FO#nK@IN<;Q literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/default-button-bezel-disabled-left.png b/AppKit/Themes/Aristo/Resources/default-button-bezel-disabled-left.png new file mode 100644 index 0000000000000000000000000000000000000000..03e468f39f383cbd52ee56d03479634e44438144 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^EI=&5!3HGnK8=|Nq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6)p30aSW-rmGtITK~HOA<3Z_;wG9ysPw(%q-?wU$kld@H zNj!7j?^n>Rzj&uHi)|KH$JQS*Y#+JXbbr{kXK4rrJox-R ze!oP5mLrpUyj}IF53kidKG<7KFyCMMbq;IC*#@g03`{%>x6S98?=9H;9Oz;OPgg&e IbxsLQ0BV6}4FCWD literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/default-button-bezel-disabled-right.png b/AppKit/Themes/Aristo/Resources/default-button-bezel-disabled-right.png new file mode 100644 index 0000000000000000000000000000000000000000..d3366babc3a92b5ccd8b9b41a1e834999c7e0e76 GIT binary patch literal 261 zcmV+g0s8)lP)@BnqJi&?+NcTs#VAa8NByH&Fo<$P+;bM0F2j?y`~g=8x#YQ5_$tU>@XtmFrt#D5%-|9 z2X`6Fzs7z{;q)GaKb}v{3Ao(9&{>OfRSKBv^=ctP6S54M+yoc^EHR_##N}Z}00000 LNkvXXu0mjfW%XxA literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/horizontal-track-disabled-center.png b/AppKit/Themes/Aristo/Resources/horizontal-track-disabled-center.png new file mode 100644 index 0000000000000000000000000000000000000000..fa421383b0b7990ef8f92b5a350eb5636921559e GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrF!3HE-TH59VDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MJk>yjv*DdlHR<3KmX*CMT-s{P*GGoc;Lw4!-o%id3su$ ct$~4=!DA5{OV8cMPC)exp00i_>zopr09C##xBvhE literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/horizontal-track-disabled-left.png b/AppKit/Themes/Aristo/Resources/horizontal-track-disabled-left.png new file mode 100644 index 0000000000000000000000000000000000000000..370897e28cb5a0a096cd198c2fcb76214c2e24fd GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c4!3HFg*81KCQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JiXuE+978H@C9PSrM&!Y>XMIV@$(K_T6BCmJ#l-v=l6>Rh z;@B1_Fn3RwFk#Y;9Tv>?_V&!$+S<&**4Dpm_4M@EBX!EiQEk!^(7(8A5T-G@yGywqk89TfH literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/horizontal-track-disabled-right.png b/AppKit/Themes/Aristo/Resources/horizontal-track-disabled-right.png new file mode 100644 index 0000000000000000000000000000000000000000..71c465d559874225713d6700f6cccc7d15638fa4 GIT binary patch literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c4!3HFg*81KCQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JilRMT978H@CB1q5diKxn@9)>!*ZF97�Wt~%&>YP(*|1zN-4>FVdQ&MBb@0Kwx*H~;_u literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/knob-disabled.png b/AppKit/Themes/Aristo/Resources/knob-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..61e860a66bcd332c92e7060d1d1dcd5095316007 GIT binary patch literal 874 zcmV-w1C{)VP)Nq zqv3F5d(#?JGyB|#?(6I0-!85^5`5k(97BiP48_)Tv##pKu3RiH-d@Au9wyq{d# zh@07L7OAR=s?{p0R4S-kE?Zw1!~ZZ3>z=-vy*4;F=xH3#z+_rDX3kw08#q03@^LUA zkRFeR&@^q&gn7MQYv1{^XJ!OJIF(MPHD?Z-YM~;Li1+s0ds6{lkIU_L6NX_lqv+%? z&v6_P7JR;kQ`0X3fq=&jvQ3I~Fc|C&_4bUhEK8WC*|oy~A;0h9(9n?J6p51-8edc3 zTr^Knl(nf_0~vEH&BJ~?%ytB47=|YaWL@hp;MM_%AYCpOXV*g;xK%J3<`KAr=({yo zujx9%H=v!IJHf5WD^*mrR;zK4&~6RupD0z;8cwp|tX5}uhOXcsbvVx+~=#xUBu(i3l3E+As&dp>pS;m#N{pI8Gye#I+t&M z8WM%7#pO@z>`Lm=(&E(5AK#+6Ty9&Eq>7XC)`aSrOh%$&eugwGZ#+pUbiw!@zO;RU9qYmZ#mc9Q_=qVn;_u1L1J^gx~Lv zVEqqZ@5Pa`IPyA9d;$B8q9{p-I2MaZAeu(oZDMu+Z}xNO6~n{BexBz8P+)d}SgOJ% zB@zk6rsAJ|eh_%;OT=_|iS&bBBJ#g|{r?Iu09c(%ArU-Up#T5?07*qoM6N<$f;>8$ A!~g&Q literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/popup-bezel-disabled-right-pullsdown.png b/AppKit/Themes/Aristo/Resources/popup-bezel-disabled-right-pullsdown.png new file mode 100644 index 0000000000000000000000000000000000000000..78249fb48f5868bd51163674e9f48e250ab98aca GIT binary patch literal 471 zcmV;|0Vw{7P)7=>8J4juYO{e%8R9jt#~)S+A2AxMLAMKf8`T-}*%W>@XzZpCbuKKPh9 z%`@*e?>95j$yxpsVx!42&oZY_N^!imDU8&ydeLI(W&i%kkQK*qPi2 zSCXzWN*!Ua9$UM|M#h;Oz$ioqXSgsDCM-l{1cZbEBTzVqu!-p4oIg+&0_;nfPZ=AH z1}<|KpoC!9k45>HALexXj^^XHC*ctsebX+CRkWngi))b@KD11+$@$?R#AKJ z20XKo^@ACtYIdQglB|ppwzm>6%nz~FH(D0bdJ50Y4%?*jJ?ndSWALWt`+BUKKfA8H zGYg~72>zd#-<8m|Iin@~TVVJ5s8=f-cIAF}?ryI|3ggzjVR`;3zyQNDb(FFk8ixP? N002ovPDHLkV1nk4&z}GQ literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/popup-bezel-disabled-right.png b/AppKit/Themes/Aristo/Resources/popup-bezel-disabled-right.png new file mode 100644 index 0000000000000000000000000000000000000000..49e583a190c9b6bcd97e843e407fcc8e4347ed0c GIT binary patch literal 614 zcmV-s0-61ZP)We1pjW30=`B@>((BDs!BMZ?GD@ca45iPN)TQ;CC=afPD~wtXdWp78X%9 zO`&y+BdjcyN}*8LhD~ftOuU68Ng~P!2yr~+>gpO)bsOydnx-L>$$DPPII?>}4|t)f zD%QWPH&0q(a=9Foh=N!w#$C@i@};u-Lf3Vqm(xwiP2jAo5s>$v`x)_0Y$G7{hWj4@p6^UCA{(xpvM35pR1wsg81PW0AJJ>v&dy&0@tTtjtx-jGMIXd^u@i6dk zFwJK3+Uay=91cg4W!cN!ZYS^e`{8D@`I^t?yZDZI0yth&tAAC0B9V9(iA1hLp%8ez zUJwKUR8@u5Y6bK89A>jwcRU_{EEbEuZ5(Tp)oL{{9*=)WrBcasIt^~O8yJQG!!Q8V z0MGM)sq3ilv zTvn(x2dO9&3V%{87JK3I`2aT$pvQ{#gTWx6>I|yCAv`Hz(L{;*-)^^X?(qBl;BvX% z;Pmc5g5xC;J&6RpA>bw9iG;x(1=@HD2@N!ux7%T`PYsLbIPPo$%nY5}ADhI)9LS5s z;);wtcPy7n%8x?$1Bs$2T~QRTC=2Hf3?0a_{DtroHh-qm>HL%=DTC&EJsuC`;J-DQ zOrYQIe=nEIpAfGTiMd{{O(Ym$&@#AoQPdwJK-DlBjnqb?aXT0cevv(P?9E=Ur%k8R zZy34=y8hfgMv6X}NFERYD)>>a*KgbH_JmXrmO1(miO`KDluD)7$z<{sdL&{NcuXpO z37Rq-4oEwdN`-t-vDS3T$0YX|qIR&JS^u2%j9#V?85Y>Eo;|z@{!ztRbH=(qsCHJJ d+$Vnp7yx2CD7km7eqaCq002ovPDHLkV1jn26|VpQ delta 578 zcmV-I0=@l>1%L&RNq-_qL_t(|+LTj0Pa;ti9cBiY8O#zSkZiVaNl+5$EX*d`QP^3T zppC`W+grE=)&2!7X|^!@0JGU_XQc&|#PAWm3=NP8@-Ym<0DI2FNz{#Iyvd#W-n;kQ zckkTu1mT6`ayhZxZhvpJTE82OMzdb8+qB&Coc@;>-_uR4R)5=+W%LRO*MKDEkaptyaQYLO)s- z(9*|vJZ?uKk$)?e6Tra%dq*{%6_+y6A*u<=C|$wfXZB5}SMm9LtZIXJ8IzC!*64Uo zlE-+3co`*$$T(dr7AmXpDu`zilX(0i7P7pb&1PG{V9;|C@&>pL@%$$?^siwUTPV$Q zlF4L3DqIpT0%$gy%`+tFj>lt9lL1G_-a9b-oOu2O3xAI8U@$lt4u=K<$c5LGeyGv! z_fLV-OQq7xc{}-h9%ENxVC-%z7W;{HiacO@?&!&4(=@5&Uaxnm>-r72)y-zJmP32A zV}Ue%IIf|`iA3TX+S>ycKEbU(O;pjrB>vz<=Osz%AgNxhR_*^@F`fX~`vJGF!-kPW z1=tTeCp!%=i3hd-J7fjVUa>25l*?ruN$vrxp`AOdZ)v&bIsH!)Q2q%p0Aw(qlpE!N Q5&!@I07*qoM6N<$g2ufUSpWb4 diff --git a/AppKit/Themes/Aristo/Resources/radio-bezel-selected-disabled.png b/AppKit/Themes/Aristo/Resources/radio-bezel-selected-disabled.png index 7d5d963dffb94a9141946ab42126fd6c6eb71bce..20858b2bd9c1669b84c0d4efb582b5d256440521 100644 GIT binary patch delta 781 zcmV+o1M>Wz2FV7HNq_4}L_t(|+I&=9NK;W9|KG1|_s-d-o0F}{Ci5#4N1|3f1QrrK z^csE8Q$0w%M$k(H(o1iF2}uu02u4KsVDuCOJtPQ{CZ^$>bE{pqxm`E!?(VtwcFx$Q zQ|!X;+;i^#{C@wB^FNn@;}7*@YA(c?%sn*A`e>T*>be%w5r2xRMP=#fovVv@k5NN7 zycm5pVfVDQ-){A~ds>jV8=y8FCW89L)o@?vvUs(7uS0H4T3>|0Ba}Kxn z?qFBIR@dNym46+%CO=8lK*FEmc;3+11buC~t+1cJg_kce5Q&7k@o;RYrz1FIX>fz2 zAkYo{MC6MaFctxL#%S_|E~Mu_e~gkySd&HQXN5Y*D{9qyCba`IljE?uya=7$A-I0; zKG+*wC7X%>1Y13DW_}Paztec&XofqDC=;kS>fhTxK^RWwSU;RK>;1Bhc(}g07*`dwAqZja`x? z$YnDk;eQj?T4F1_;`RmnJT7kKA@kwkOEpK0kam!+D8irc`V!%nnk~BeBiqv5*UgyB zf|(aU*Y*D*5#NT*)#dQ)_}C{*&k+$rL#lzBCuMaucL7Clyw!SQpAdmqWJCV;;mtcK z`8R?2N~P`fR6MdTMt*M!4wp+ez)r3eRVo<;YJX9M9Iink7KP1U%aN}$lkel}Kcm=~ zCtT{#MI`mHVK@e^-3++{?Pqw~DJR2n7943o-peKv;kA|d*=cf%(9yNq@mfL_t(|+Jsa|PgFq=uGep$#}*h_;(`NCFqwFOgt$ZrH{-#B z7Y_UckNyC;6XVg7UP#1*t7i|IxMdJy$QThvmIRo4_WnBO&ib62@X7&#Fw>(G*zInDTOc<$v9inVFfm6{EENWOM76 zg=Q|=mO0+-*pM&{6dgQXM+u?q`rrrrGmH4_WG4NsiDT5w&CRjw*B?^>=*zub9pmTv z`#?8sa0P>1H)@RZPwS*7yAP{tR|rRVjk;?$r#b_{UJNC>9m7t*0Rmeak0o#%tJv8I z2L_~c4oc#ACV!K;ip#!AF&G#bd+0dM9nE$cfd74U)H6*7knw=i(+?5Hb^!U?B@?6jj|Yp;E5QApQ}PNG*)zumBYVZqk(1 zPgxA42UbtAF@9P8*rtypL#OgQ;Wcb#EQBS=gZRUQvVUQA_5f3L1l7TJD{Xo>vbPAY zDT<;>83$1mS&Xq`gYMow@aqB;T*KVpe-cE?CPLt$M9c|K$BAWB-{U-JcxuYUkx}Sy z5+HF-V`}tLo1Sw{3=4$UkO7xr@YZv^l!n1=HkzkWsW$qpOgz^G!Tr~SXGq5_?`}N{ zYL!y0T7PXAo+i~w8F;O{ak#Vbl<>?j3|CQLvtHhxuO5~HGB|C6TKO>Wi+l5`s%|&% zL~UVVfzmXp8rHPYJNQ6PbPiisxpX87Hi4sh2!ZcG-K%berNZMl3|=ATCtgOsQTF+K z-cP5~n}CYiPJTO)9Gc~>eH}~l45r>hPZ-7M09!);y;s~@#3Ou12HUw@j{kLw@e0^+ z94ApOVAKb3>^dp|86))y&I@z|lp-Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JiflYx978H@*__;<)EubWn~HcfgsyU*5~PFmFyZ zdm40k2KQ|qLB>fFSjzXQ$=3D$@>kq)t)GFJ;p1Yhz4zB;Xamh*@O1TaS?83{1OVSv BF{=Oo literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/scroller-horizontal-knob-disabled-left.png b/AppKit/Themes/Aristo/Resources/scroller-horizontal-knob-disabled-left.png new file mode 100644 index 0000000000000000000000000000000000000000..1417e8c3412287d4c6ad6f3466c127e69aaee2c3 GIT binary patch literal 436 zcmV;l0ZaagP)K@^4W{II*ifP>%) zRumc%qlFpn7;-)D@0<2bRW;TSwS zzo?hX%k5IB%ojO_FbrX=E&KgHuo-Q;?#fefsmLwc2H*E#Ry66FxxTq=WpmkGLMR9! z;6Kr%t3?PoHg%)X2YmPAH3gIW(>Cz$pP-by zB7~0=DBH1}xvMz&DV>&P(qTs84~t79=(n-l&a68`KyYSs|Km+gX?0x$SsnS^J{8 z^UtKNt{WNvLd<8abyEmlKRP_9V=d!#^FNAI+wLHvfiVU_5P<8t;CWw-Znv{_T&vmf zrf7pTavX3d1tBFYW-?GJm7rK$UN4td?l!B{3Nplq8ki`hq88JykD1A4A)hZ4q*NzZ zuEpahO9%n;>H9vU34vTLSJ~d#t0K5y)Gdka|4Pm|s4xUV(i<^s5zYl91)dui=c_Z= zv`vZ-l|65~6d%&SJQ3!T`RU9J{*SUtUE}@B)Mp}vOoRu60V^q3BM#j{%sHzGq z%i3GK*=#7hF;!)hs+RvFCcfZ&Y##J_ixbB=HyJyk0`w+CRITAQA~w)qyG97Z5LT;r z{^UO1G0%Ihl4L!MqHtZ71u(|`yfKbrLi+vnc}oqLwr$I~>qheR7z~I*R@0-qSJyWejG03vI?apXuq?|&8MG{l{9!ho zj1;F(D5-8MZVOP)9gVJnsn3vphy)5k19vT!nt(c4X`!KWxC7e5j{pMz+Xv87014kE P00000NkvXXu0mjf4qCHR literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/scroller-vertical-knob-disabled-center.png b/AppKit/Themes/Aristo/Resources/scroller-vertical-knob-disabled-center.png new file mode 100644 index 0000000000000000000000000000000000000000..2756a41caf48223caedd31fc5c418b0c4ef3b47f GIT binary patch literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^{6Nge!2~4x_9f>6DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MTVX(jv*DdlJ4w&->_=ctM-2R|Ns8}{{8*Eef_^bzrITI qIDC;;VB!Av^Y`;tSF;%y*%)%pX{4VG-@Y2CnZeW5&t;ucLK6UXG&P(6 literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/scroller-vertical-knob-disabled-top.png b/AppKit/Themes/Aristo/Resources/scroller-vertical-knob-disabled-top.png new file mode 100644 index 0000000000000000000000000000000000000000..6ca32cb884164f357160dd5282202ae210e94149 GIT binary patch literal 424 zcmV;Z0ayNsP)pmJa)55b~6b{ zER>*VA(}!&)N*UF@_`sjOP`gW;8)n%TiB_j_Xotnko5}^*svq}nDLHm5kxUwILw{l zo|!u{#P@yp76hR=BuD3{9Fqh8K{9I=Vk2x!&X5>Mkko9#$3&CcC#Po}#`sno$8Gr` z7ote^rIfEyM&0hy;~mySIWfVuzr@2%XRg(ny(yN8zET>pOaY}7!chpLFoeNy2*bhP zx!-%c3W9zQozR@d&Mz)kJkNU&)oP7%3-DAVfh0+w=s3U_gL2sg&iH1UX7?KO{(BI- z(50ni2c6qybE;M|6H_V+Po~-c6`6RtIEGZ*O1iPT{Jl@x|NsBbr~LZ%R+{_5liAcH^x1OHC|6H_V+Po~-c6={09IEGZ*O1iPT{Jqbz|Ns9RD+vDo_qSOnBgW*>`}_MV hQZ`C5Y-d(Dz;I8^z5RsBntGrn22WQ%mvv4FO#osiE^q(< literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/segmented-control-bezel-disabled-left.png b/AppKit/Themes/Aristo/Resources/segmented-control-bezel-disabled-left.png new file mode 100644 index 0000000000000000000000000000000000000000..cb7c29f61bd3a6f5dfcea4b4f10cf60b10f31091 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^EI=&5!3HGnK8=|Nq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c71epVIEGZ*O1iVVT%Vhnx!GJGnsFn;>Hq)#*QTbX+CF*u zRPx5no02mcn64Qa8S(u8_c!^+x3|*F+!GFRKRUqR!OhHZnAKsEhSmv@AHTor%Wk=F zgeQeDK%nm5*Vp3AItykrY;vD(Q+epa=jZ+#yaELB>i+$)|6H_V+Po~-c6;*n=IEGZ*O1iVV{JjqwTN}Sa4Nu2*qksSZ*FQTy-(FJA zuI9vtA0Hpf`rO}FoBZSZd->*`9v?y7QELDI literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/segmented-control-bezel-highlighted-disabled-center.png b/AppKit/Themes/Aristo/Resources/segmented-control-bezel-highlighted-disabled-center.png new file mode 100644 index 0000000000000000000000000000000000000000..eb00afc1fd3d50a1058edd3ebe1456061aaf73ce GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{G!3HF)&rH7sq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c71?{bIEGZ*N_usxAV)2D$!1CB%UieGOV0TB_cy=NKSP7R ztbzj9;tjs*_p}~y?fBdJ$|1NXP2|Rp)zAHm7+542R{wM{zSDiP2xt_8r>mdKI;Vst E0G&iPd;kCd literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/segmented-control-bezel-highlighted-disabled-divider.png b/AppKit/Themes/Aristo/Resources/segmented-control-bezel-highlighted-disabled-divider.png new file mode 100644 index 0000000000000000000000000000000000000000..84cde75b9d52dfe1983a3fdec9df5ccf4523a804 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{G!3HF)&rH7sq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6&ZQDIEGZ*N_usxAV=-;{`&tCGyeVmf1V*RQJ`LO#=n0@ rkNx5fWlB?25lFgmhB=Z&Ac0|@sk`yh1$&)|6H_V+Po~-c6)p92aSW-rmGtITK~HOA<3Z_;wG9ysPw(%q-zQZhBsYsI zh$rSv4v)_N|Npm(O`niZ@u|1*;rZ$Fc@#wV$k#E78vkJyOkiXaXk*-PAijjrM6_P= z-#=F&hQfbLteh);bmy^cnzp~*G3wu;4lS)E6k^*Zh8EDJ(FXvGfBYiv+`^*tvRI92QT34rcIl^>bP0 Hl+XkKXa8d` literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/segmented-control-bezel-highlighted-disabled-right.png b/AppKit/Themes/Aristo/Resources/segmented-control-bezel-highlighted-disabled-right.png new file mode 100644 index 0000000000000000000000000000000000000000..a932e6ac62827cafaba2826d144025a74af4cf97 GIT binary patch literal 261 zcmV+g0s8)lP)k0 zSZ$7@*5X`ZR{)(jhI6iKm>nvO_{`iEz<4d)8w$a8U}fi7AzZCsS>Jiu62P978ywlcP2yFi!67=Dyr5u0P}7|NrN|yuWWR^5^^e nc!Rc$8#@o)c=6-XQf~&$7tW2&w!BY)IvG4&{an^LB{Ts5`QI@v diff --git a/AppKit/Themes/Aristo/Resources/segmented-control-bezel-inactive-divider.png b/AppKit/Themes/Aristo/Resources/segmented-control-bezel-inactive-divider.png deleted file mode 100644 index 74f4ba883892faa7db3aee924c1811f0f2a8c737..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{G!2~3?tYhc}Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jiqt(_978ywlcP2yFkaqY|9{56|Nr@yUHo`|fBnW!jwYLA fI(qZiCh#+`U3Y5?cD*(asD;7P)z4*}Q$iB}ja4h@ diff --git a/AppKit/Themes/Aristo/Resources/segmented-control-bezel-inactive-left.png b/AppKit/Themes/Aristo/Resources/segmented-control-bezel-inactive-left.png deleted file mode 100644 index cac177496b10a6db81cb8f745d6ad6173f29f5bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^EI=&5!3HGnK8=|Nq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6}5S~IEF}sCr52aV3Zcv&hSxK;otc$@9*z-i;TRPB`qzT zDK0L~w(S4^|LWbHorX34{>*%Mv|F4gTe~DWM4f*ehA# diff --git a/AppKit/Themes/Aristo/Resources/segmented-control-bezel-inactive-right.png b/AppKit/Themes/Aristo/Resources/segmented-control-bezel-inactive-right.png deleted file mode 100644 index d04835db2f5447a3af48695fe98e7f3287072a67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^EI=&5!3HGnK8=|Nq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6}5S~IEF}s&+WJ6I^-bIvj0Tf!I%r#5s{TWYi$DZHcU8h zXxi;175Vd~E>h93dV2hif%7@b2G$b?QfEB3yjHq&ij(Hksuf!=Rj13iD?OT`#AJN< z%!Cr3NfjPK{~5~bnabD;Q51eJLt~7Bif9~A z8&tX|Z8xsEiHSi2qS!3z4{+nO^(Tnfof9acA_y&L7rF_FrQKxVMr>`dWTCOn^B6Pd z^?d1jlEftDX#y^K;gC1o^L_6-=bn3BSdQbEr!d(6MB)))SvKiO)6>(k{QUe2#rAnHbXZ^YgD13dLKAMDij#J6oYrscv5YFXVJO8M$2U z@%#P1Jsyv(sj2D5;^HEgDn;12xw#4gZ6y^d3JVLFoSdA{^OzexU$}ODe$E^m95AGg zgUEd}nM@9=)f$sfU0q#LM4*D6RCrfiT`eUd481KA2m}(oom47iWHK3uFm}5=KlouUavQ# z#A6IT;0r$C+h{bh!aZTcS~U_%MpI>Fr4+Fi8;(SI1D_Ns6P1A`8~6Gk8=k>=)RB^9Kq%*@QR z5rJ=D0E<+*jzxskYPA|-D~ZnNR1aVPtEHu7mE(aTh*05D6Wg?@Aq-&93M!(*pV%Fu zi6C)RSoi5B!fyqcJZA7tj!*##W%7L`{IP?_h$!U|M5yq%eLi2>6#)jY;u1MIIoZFt zxk)<_U;rx~k>J9@!Y1vq9Ap#ID2W+ZBo`MK9I%A^h$h0VuCBVMf7rOZywp(RlNKUZ zS667DHh?9pm^(y}uUlJNOKP+{Z#7V>$D+#;GtSP=(5rG}*8cu}kic&19T^$9WzgQFFuLvA4XuY@V5!K{%WsF+4mRv8{J>bR_pV z!RL_@*4EbcQlrtlp-u}OoLs3?Mm&r#Twh=N$Trs3*H^~J$A6)a^5O6g4GrDtEjl|p zlmEctb4gC7fKivF)a&&{)SautKRLIzxA$!}+y36(9>6`k`EYM=a4=?r)78}_`rB6^ z1cjvhuY|uYtT-gPpDzRW4Gs(pBO`H literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/vertical-track-disabled-bottom.png b/AppKit/Themes/Aristo/Resources/vertical-track-disabled-bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..5ff3530fb6cc119da908a9b812d2c366421d4303 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1d!3HGVjK4YnDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MLwP`jv*Dde2(tsZ7|?rJ<$G|=fTyL6CxBh2OMP3{Og&j z%v7T3xBW^~c$%9g>)!G$*Bp|2em9?V7A#CtQxo6$d)=z`jtBS8YzuE-WY{KaEw^Gh R&my3?44$rjF6*2UngExMItTy& literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/Resources/vertical-track-disabled-center.png b/AppKit/Themes/Aristo/Resources/vertical-track-disabled-center.png new file mode 100644 index 0000000000000000000000000000000000000000..ca474fce8b0fb205986a8f1f14fd96068a64b957 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1j!3HG7{-t~dQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JiWEFu978H@CEeLm`Pqk)laozOPOeQqexJdfijPf<3I`ZM XDSr z1<%~X^wgl##FWaylc_d9MVX#1jv*DdlGdzQBl6(Uqpqa1v}^xqe=%Ht5q)6>(VrL$+x9-Tjb{_xn?*zf=i v;<>-SK0PTZIhnb5f}wDLC9@S9hXF$}yM#g~_o}}@OBp;}{an^LB{Ts5GYUyg literal 0 HcmV?d00001 diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j index 25cfccaba..dc75cf4a5 100644 --- a/AppKit/Themes/Aristo/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo/ThemeDescriptors.j @@ -54,6 +54,14 @@ [_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)] ] isVertical:NO]], + + defaultDisabledBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"default-button-bezel-disabled-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"default-button-bezel-disabled-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"default-button-bezel-disabled-right.png" size:CGSizeMake(4.0, 24.0)] + ] + isVertical:NO]], disabledBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: [ @@ -66,6 +74,7 @@ [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered]; [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"]; [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateBordered]; + [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:0.6] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateBordered|CPThemeStateDisabled]; [button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateBordered]; [button setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"]; @@ -74,12 +83,13 @@ [button setValue:CGInsetMake(0.0, 5.0, 0.0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; [button setValue:[CPColor colorWithCalibratedWhite:0.6 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDisabled]; - [button setValue:disabledBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled]; - [button setValue:disabledBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDefault|CPThemeStateDisabled]; + [button setValue:disabledBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDisabled]; + [button setValue:defaultDisabledBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDefault|CPThemeStateDisabled]; [button setValue:defaultBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDefault]; [button setValue:defaultHighlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted|CPThemeStateDefault]; [button setValue:[CPColor colorWithCalibratedRed:13.0/255.0 green:51.0/255.0 blue:70.0/255.0 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDefault]; + [button setValue:[CPColor colorWithCalibratedRed:13.0/255.0 green:51.0/255.0 blue:70.0/255.0 alpha:0.6] forThemeAttribute:@"text-color" inState:CPThemeStateDisabled|CPThemeStateDefault]; [button setValue:CGSizeMake(0.0, 24.0) forThemeAttribute:@"min-size"]; [button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"]; @@ -116,10 +126,20 @@ [_CPCibCustomResource imageResourceWithName:"popup-bezel-right.png" size:CGSizeMake(27.0, 24.0)] ] isVertical:NO]]; - + + var disabledBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"button-bezel-disabled-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-disabled-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"popup-bezel-disabled-right.png" size:CGSizeMake(27.0, 24.0)] + ] + isVertical:NO]]; + [button setTitle:@"Pop Up"]; [button setValue:color forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; + [button setValue:disabledBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDisabled]; + [button setValue:CGInsetMake(0, 27.0 + 5.0, 0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"]; [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"]; @@ -130,6 +150,9 @@ [button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"]; [button addItemWithTitle:@"item"]; + + [button setValue:[CPColor colorWithCalibratedWhite:0.6 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateBordered|CPThemeStateDisabled]; + [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:0.6] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateBordered|CPThemeStateDisabled]; return button; } @@ -145,9 +168,19 @@ ] isVertical:NO]]; + var disabledColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"button-bezel-disabled-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-disabled-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"popup-bezel-disabled-right-pullsdown.png" size:CGSizeMake(27.0, 24.0)] + ] + isVertical:NO]]; + [button setTitle:@"Pull Down"]; [button setValue:color forThemeAttribute:@"bezel-color" inState:CPPopUpButtonStatePullsDown|CPThemeStateBordered]; + [button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled|CPPopUpButtonStatePullsDown|CPThemeStateBordered]; + [button setValue:CGInsetMake(0, 27.0 + 5.0, 0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"]; [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"]; @@ -157,6 +190,9 @@ [button setValue:CGSizeMake(32.0, 24.0) forThemeAttribute:@"min-size"]; [button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"]; + [button setValue:[CPColor colorWithCalibratedWhite:0.6 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateBordered|CPThemeStateDisabled]; + [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:0.6] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateBordered|CPThemeStateDisabled]; + [button addItemWithTitle:@"item"]; return button; @@ -200,8 +236,17 @@ [_CPCibCustomResource imageResourceWithName:"scroller-vertical-knob-bottom.png" size:CGSizeMake(15.0, 10.0)] ] isVertical:YES]); + + var knobDisabledColor = PatternColor([[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"scroller-vertical-knob-disabled-top.png" size:CGSizeMake(15.0, 10.0)], + [_CPCibCustomResource imageResourceWithName:"scroller-vertical-knob-disabled-center.png" size:CGSizeMake(15.0, 1.0)], + [_CPCibCustomResource imageResourceWithName:"scroller-vertical-knob-disabled-bottom.png" size:CGSizeMake(15.0, 10.0)] + ] + isVertical:YES]); [scroller setValue:knobColor forThemeAttribute:@"knob-color" inState:CPThemeStateVertical]; + [scroller setValue:knobDisabledColor forThemeAttribute:@"knob-color" inState:CPThemeStateVertical|CPThemeStateDisabled]; [scroller setFloatValue:0.1]; [scroller setKnobProportion:0.5]; @@ -248,7 +293,16 @@ ] isVertical:NO]); + var knobDisabledColor = PatternColor([[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"scroller-horizontal-knob-disabled-left.png" size:CGSizeMake(10.0, 15.0)], + [_CPCibCustomResource imageResourceWithName:"scroller-horizontal-knob-disabled-center.png" size:CGSizeMake(1.0, 15.0)], + [_CPCibCustomResource imageResourceWithName:"scroller-horizontal-knob-disabled-right.png" size:CGSizeMake(10.0, 15.0)] + ] + isVertical:NO]); + [scroller setValue:knobColor forThemeAttribute:@"knob-color"]; + [scroller setValue:knobDisabledColor forThemeAttribute:@"knob-color" inState:CPThemeStateDisabled]; [scroller setFloatValue:0.1]; [scroller setKnobProportion:0.5]; @@ -351,6 +405,8 @@ [button setTitle:@"Hello Friend!"]; + [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDisabled]; + var bezelColor = PatternColor([[CPThreePartImage alloc] initWithImageSlices: [ [_CPCibCustomResource imageResourceWithName:"radio-bezel.png" size:CGSizeMake(17.0, 17.0)], nil, nil @@ -403,6 +459,8 @@ [button setTitle:@"Another option"]; + [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDisabled]; + var bezelColor = PatternColor([[CPThreePartImage alloc] initWithImageSlices: [ [_CPCibCustomResource imageResourceWithName:"check-box-bezel.png" size:CGSizeMake(15.0, 16.0)], nil, nil @@ -499,7 +557,7 @@ [segmentedControl setLabel:@"bar" forSegment:1]; [segmentedControl setTag:2 forSegment:1]; - [segmentedControl setWidth:25.0 forSegment:2]; + [segmentedControl setWidth:35.0 forSegment:2]; [segmentedControl setLabel:@"1" forSegment:2]; [segmentedControl setTag:3 forSegment:2]; @@ -510,10 +568,14 @@ dividerHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-divider.png" size:CGSizeMake(1.0, 24.0)]), leftHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)]), rightHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]), - inactiveCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-center.png" size:CGSizeMake(1.0, 24.0)]), - inactiveDividerBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-divider.png" size:CGSizeMake(1.0, 24.0)]), - inactiveLeftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-left.png" size:CGSizeMake(4.0, 24.0)]), - inactiveRightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-right.png" size:CGSizeMake(4.0, 24.0)]), + inactiveCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-disabled-center.png" size:CGSizeMake(1.0, 24.0)]), + inactiveDividerBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-disabled-divider.png" size:CGSizeMake(1.0, 24.0)]), + inactiveLeftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-disabled-left.png" size:CGSizeMake(4.0, 24.0)]), + inactiveRightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-disabled-right.png" size:CGSizeMake(4.0, 24.0)]), + inactiveHighlightedCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-disabled-center.png" size:CGSizeMake(1.0, 24.0)]), + inactiveHighlightedDividerBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-disabled-divider.png" size:CGSizeMake(1.0, 24.0)]), + inactiveHighlightedLeftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-disabled-left.png" size:CGSizeMake(4.0, 24.0)]), + inactiveHighlightedRightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-disabled-right.png" size:CGSizeMake(4.0, 24.0)]), leftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-left.png" size:CGSizeMake(4.0, 24.0)]), rightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-right.png" size:CGSizeMake(4.0, 24.0)]), pushedCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-center.png" size:CGSizeMake(1.0, 24.0)]), @@ -525,23 +587,27 @@ [segmentedControl setValue:centerBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateNormal]; [segmentedControl setValue:inactiveCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateDisabled]; + [segmentedControl setValue:inactiveHighlightedCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateSelected|CPThemeStateDisabled]; [segmentedControl setValue:centerHighlightedBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateSelected]; [segmentedControl setValue:pushedCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateHighlighted]; [segmentedControl setValue:pushedHighlightedCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateHighlighted|CPThemeStateSelected]; [segmentedControl setValue:dividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateNormal]; [segmentedControl setValue:inactiveDividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateDisabled]; + [segmentedControl setValue:inactiveHighlightedDividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateSelected|CPThemeStateDisabled]; [segmentedControl setValue:dividerHighlightedBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateSelected]; [segmentedControl setValue:dividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateHighlighted]; [segmentedControl setValue:rightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateNormal]; [segmentedControl setValue:inactiveRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateDisabled]; + [segmentedControl setValue:inactiveHighlightedRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateSelected|CPThemeStateDisabled]; [segmentedControl setValue:rightHighlightedBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateSelected]; [segmentedControl setValue:pushedRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateHighlighted]; [segmentedControl setValue:pushedHighlightedRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateHighlighted|CPThemeStateSelected]; [segmentedControl setValue:leftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateNormal]; [segmentedControl setValue:inactiveLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateDisabled]; + [segmentedControl setValue:inactiveHighlightedLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateSelected|CPThemeStateDisabled]; [segmentedControl setValue:leftHighlightedBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateSelected]; [segmentedControl setValue:pushedLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateHighlighted]; [segmentedControl setValue:pushedHighlightedLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateHighlighted|CPThemeStateSelected]; @@ -571,17 +637,28 @@ [_CPCibCustomResource imageResourceWithName:"horizontal-track-center.png" size:CGSizeMake(1.0, 5.0)], [_CPCibCustomResource imageResourceWithName:"horizontal-track-right.png" size:CGSizeMake(4.0, 5.0)] ] + isVertical:NO]], + + trackDisabledColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"horizontal-track-disabled-left.png" size:CGSizeMake(4.0, 5.0)], + [_CPCibCustomResource imageResourceWithName:"horizontal-track-disabled-center.png" size:CGSizeMake(1.0, 5.0)], + [_CPCibCustomResource imageResourceWithName:"horizontal-track-disabled-right.png" size:CGSizeMake(4.0, 5.0)] + ] isVertical:NO]]; [slider setValue:5.0 forThemeAttribute:@"track-width"]; [slider setValue:trackColor forThemeAttribute:@"track-color"]; + [slider setValue:trackDisabledColor forThemeAttribute:@"track-color" inState:CPThemeStateDisabled]; - var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob.png" size:CGSizeMake(23.0, 24.0)]]; - knobHighlightedColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob-highlighted.png" size:CGSizeMake(23.0, 24.0)]]; + var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob.png" size:CGSizeMake(23.0, 24.0)]], + knobHighlightedColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob-highlighted.png" size:CGSizeMake(23.0, 24.0)]], + knobDisabledColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob-disabled.png" size:CGSizeMake(23.0, 24.0)]]; [slider setValue:CGSizeMake(23.0, 24.0) forThemeAttribute:@"knob-size"]; [slider setValue:knobColor forThemeAttribute:@"knob-color"]; [slider setValue:knobHighlightedColor forThemeAttribute:@"knob-color" inState:CPThemeStateHighlighted]; + [slider setValue:knobDisabledColor forThemeAttribute:@"knob-color" inState:CPThemeStateDisabled]; return slider; } @@ -595,17 +672,27 @@ [_CPCibCustomResource imageResourceWithName:"vertical-track-center.png" size:CGSizeMake(5.0, 1.0)], [_CPCibCustomResource imageResourceWithName:"vertical-track-bottom.png" size:CGSizeMake(5.0, 4.0)] ] + isVertical:YES]], + trackDisabledColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"vertical-track-disabled-top.png" size:CGSizeMake(5.0, 6.0)], + [_CPCibCustomResource imageResourceWithName:"vertical-track-disabled-center.png" size:CGSizeMake(5.0, 1.0)], + [_CPCibCustomResource imageResourceWithName:"vertical-track-disabled-bottom.png" size:CGSizeMake(5.0, 4.0)] + ] isVertical:YES]]; [slider setValue:5.0 forThemeAttribute:@"track-width"]; [slider setValue:trackColor forThemeAttribute:@"track-color" inState:CPThemeStateVertical]; + [slider setValue:trackDisabledColor forThemeAttribute:@"track-color" inState:CPThemeStateDisabled]; - var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob.png" size:CGSizeMake(23.0, 24.0)]]; - knobHighlightedColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob-highlighted.png" size:CGSizeMake(23.0, 24.0)]]; - + var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob.png" size:CGSizeMake(23.0, 24.0)]], + knobHighlightedColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob-highlighted.png" size:CGSizeMake(23.0, 24.0)]], + knobDisabledColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob-disabled.png" size:CGSizeMake(23.0, 24.0)]]; + [slider setValue:CGSizeMake(23.0, 24.0) forThemeAttribute:@"knob-size"]; [slider setValue:knobColor forThemeAttribute:@"knob-color"]; [slider setValue:knobHighlightedColor forThemeAttribute:@"knob-color" inState:CPThemeStateHighlighted]; + [slider setValue:knobDisabledColor forThemeAttribute:@"knob-color" inState:CPThemeStateDisabled]; return slider; } @@ -613,16 +700,20 @@ + (CPSlider)themedCircularSlider { var slider = [[CPSlider alloc] initWithFrame:CGRectMake(0.0, 0.0, 34.0, 34.0)], - trackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"slider-circular-bezel.png" size:CGSizeMake(34.0, 34.0)]); + trackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"slider-circular-bezel.png" size:CGSizeMake(34.0, 34.0)]), + trackDisabledColor = PatternColor([_CPCibCustomResource imageResourceWithName:"slider-circular-disabled-bezel.png" size:CGSizeMake(34.0, 34.0)]); [slider setSliderType:CPCircularSlider]; [slider setValue:trackColor forThemeAttribute:@"track-color" inState:CPThemeStateCircular]; + [slider setValue:trackDisabledColor forThemeAttribute:@"track-color" inState:CPThemeStateDisabled|CPThemeStateCircular]; var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"slider-circular-knob.png" size:CGSizeMake(5.0, 5.0)]], + knobDisabledColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"slider-circular-disabled-knob.png" size:CGSizeMake(5.0, 5.0)]], knobHighlightedColor = knobColor; [slider setValue:CGSizeMake(5.0, 5.0) forThemeAttribute:@"knob-size" inState:CPThemeStateCircular]; [slider setValue:knobColor forThemeAttribute:@"knob-color" inState:CPThemeStateCircular]; + [slider setValue:knobDisabledColor forThemeAttribute:@"knob-color" inState:CPThemeStateDisabled|CPThemeStateCircular]; [slider setValue:knobHighlightedColor forThemeAttribute:@"knob-color" inState:CPThemeStateCircular|CPThemeStateHighlighted]; return slider; From df8c648d7030fcdd982ef352388c75002ad25080 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Fri, 30 Oct 2009 10:53:47 -0700 Subject: [PATCH 44/58] Add an unsaved state affordance to the close button on standard windows. --- AppKit/CPWindow/CPWindow.j | 2 ++ AppKit/CPWindow/_CPStandardWindowView.j | 45 +++++++++++++++++++------ AppKit/CPWindow/_CPWindowView.j | 4 +++ AppKit/CPWindowController.j | 21 ++++++++++++ 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 59c0c3501..32509b2d3 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1510,6 +1510,8 @@ CPTexturedBackgroundWindowMask _isDocumentEdited = isDocumentEdited; [CPMenu _setMenuBarIconImageAlphaValue:_isDocumentEdited ? 0.5 : 1.0]; + + [_windowView setDocumentEdited:isDocumentEdited]; } /*! diff --git a/AppKit/CPWindow/_CPStandardWindowView.j b/AppKit/CPWindow/_CPStandardWindowView.j index 5b100a2cc..8ea33a72e 100644 --- a/AppKit/CPWindow/_CPStandardWindowView.j +++ b/AppKit/CPWindow/_CPStandardWindowView.j @@ -94,13 +94,15 @@ var _CPTexturedWindowHeadGradientColor = nil, @end -var _CPStandardWindowViewBodyBackgroundColor = nil, - _CPStandardWindowViewDividerBackgroundColor = nil, - _CPStandardWindowViewTitleBackgroundColor = nil, - _CPStandardWindowViewCloseButtonImage = nil, - _CPStandardWindowViewCloseButtonHighlightedImage = nil, - _CPStandardWindowViewMinimizeButtonImage = nil, - _CPStandardWindowViewMinimizeButtonHighlightedImage = nil; +var _CPStandardWindowViewBodyBackgroundColor = nil, + _CPStandardWindowViewDividerBackgroundColor = nil, + _CPStandardWindowViewTitleBackgroundColor = nil, + _CPStandardWindowViewCloseButtonImage = nil, + _CPStandardWindowViewCloseButtonHighlightedImage = nil, + _CPStandardWindowViewCloseButtonUnsavedImage = nil, + _CPStandardWindowViewCloseButtonUnsavedHighlightedImage = nil, + _CPStandardWindowViewMinimizeButtonImage = nil, + _CPStandardWindowViewMinimizeButtonHighlightedImage = nil; var STANDARD_GRADIENT_HEIGHT = 41.0; STANDARD_TITLEBAR_HEIGHT = 25.0; @@ -115,6 +117,8 @@ var STANDARD_GRADIENT_HEIGHT = 41.0; CPTextField _titleField; CPButton _closeButton; CPButton _minimizeButton; + + BOOL _isDocumentEdited; } + (CPColor)bodyBackgroundColor @@ -262,14 +266,14 @@ var STANDARD_GRADIENT_HEIGHT = 41.0; _CPStandardWindowViewCloseButtonImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButton.png"] size:CGSizeMake(16.0, 16.0)]; _CPStandardWindowViewCloseButtonHighlightedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButtonHighlighted.png"] size:CGSizeMake(16.0, 16.0)]; + _CPStandardWindowViewCloseButtonUnsavedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButtonUnsaved.png"] size:CGSizeMake(16.0, 16.0)]; + _CPStandardWindowViewCloseButtonUnsavedHighlightedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButtonUnsavedHighlighted.png"] size:CGSizeMake(16.0, 16.0)]; } _closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 7.0, 16.0, 16.0)]; [_closeButton setBordered:NO]; - - [_closeButton setImage:_CPStandardWindowViewCloseButtonImage]; - [_closeButton setAlternateImage:_CPStandardWindowViewCloseButtonHighlightedImage]; + [self _updateCloseButton]; [self addSubview:_closeButton]; } @@ -367,6 +371,27 @@ var STANDARD_GRADIENT_HEIGHT = 41.0; } } */ + +- (void)_updateCloseButton +{ + if (_isDocumentEdited) + { + [_closeButton setImage:_CPStandardWindowViewCloseButtonUnsavedImage]; + [_closeButton setAlternateImage:_CPStandardWindowViewCloseButtonUnsavedHighlightedImage]; + } + else + { + [_closeButton setImage:_CPStandardWindowViewCloseButtonImage]; + [_closeButton setAlternateImage:_CPStandardWindowViewCloseButtonHighlightedImage]; + } +} + +- (void)setDocumentEdited:(BOOL)isEdited +{ + _isDocumentEdited = isEdited; + [self _updateCloseButton]; +} + - (void)setTitle:(CPString)aTitle { [_titleField setStringValue:aTitle]; diff --git a/AppKit/CPWindow/_CPWindowView.j b/AppKit/CPWindow/_CPWindowView.j index 5231016f6..0f878fd9a 100644 --- a/AppKit/CPWindow/_CPWindowView.j +++ b/AppKit/CPWindow/_CPWindowView.j @@ -88,6 +88,10 @@ var _CPWindowViewResizeIndicatorImage = nil; return self; } +- (void)setDocumentEdited:(BOOL)isEdited +{ +} + - (void)setTitle:(CPString)aTitle { } diff --git a/AppKit/CPWindowController.j b/AppKit/CPWindowController.j index 5909e2d63..aaaf14291 100644 --- a/AppKit/CPWindowController.j +++ b/AppKit/CPWindowController.j @@ -399,6 +399,27 @@ */ - (void)setDocumentEdited:(BOOL)isEdited { + // we ignore this. in a multi-doc world, we base this flag on the logical OR + // of all the open documents edited state. so this is just a hint to re-check that state. + //[[self window] setDocumentEdited:isEdited]; + [self _synchronizeDocumentEditedState]; +} + +- (void)_synchronizeDocumentEditedState +{ + var docs = [self documents], + count = [docs count], + isEdited = NO; + + while (count--) + { + if ([docs[count] isDocumentEdited]) + { + isEdited = YES; + break; + } + } + [[self window] setDocumentEdited:isEdited]; } From 3dbddcf1862dbc96f499dc2f989f1266a514043d Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Fri, 30 Oct 2009 18:02:33 -0700 Subject: [PATCH 45/58] Added makeObjectsPerformSelector:withObjects:. Reviewed by me. --- AppKit/CPMenu.j | 11 ++++++++--- Foundation/CPArray.j | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index ad0e2dad7..37e55757a 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -1050,7 +1050,7 @@ var STICKY_TIME_INTERVAL = 500, [_menuView setFont:aFont]; } -- (void)setBackgroundStyle:(_CPMenuWindowBackgroundStyle)aBackgroundStyle ++ (CPColor)backgroundColorForBackgroundStyle:(_CPMenuWindowBackgroundStyle)aBackgroundStyle { var color = _CPMenuWindowBackgroundColors[aBackgroundStyle]; @@ -1092,8 +1092,13 @@ var STICKY_TIME_INTERVAL = 500, _CPMenuWindowBackgroundColors[aBackgroundStyle] = color; } - - [self setBackgroundColor:color]; + + return color; +} + +- (void)setBackgroundStyle:(_CPMenuWindowBackgroundStyle)aBackgroundStyle +{ + [self setBackgroundColor:[[self class] backgroundColorForBackgroundStyle:aBackgroundStyle]]; } - (void)setMenu:(CPMenu)aMenu diff --git a/Foundation/CPArray.j b/Foundation/CPArray.j index 566eb57bb..6f17532a9 100755 --- a/Foundation/CPArray.j +++ b/Foundation/CPArray.j @@ -602,6 +602,23 @@ objj_msgSend(self[index], aSelector, anObject); } +- (void)makeObjectsPerformSelector:(SEL)aSelector withObjects:(CPArray)objects +{ + if (!aSelector) + [CPException raise:CPInvalidArgumentException reason:"makeObjectsPerformSelector:withObjects: 'aSelector' can't be nil"]; + + var index = 0, + count = length, + argumentsArray = [nil, aSelector].concat(objects || []); + + for(; index < count; ++index) + { + argumentsArray[0] = self[index]; + objj_msgSend.apply(this, argumentsArray); + } +} + + // Comparing arrays /*! Returns the first object found in the receiver (starting at index 0) which is present in the From 9ca96bc909ce752f0465f81e9feae4441deb56b8 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Sat, 31 Oct 2009 09:52:26 -0700 Subject: [PATCH 46/58] Add desktop support for recent file list --- AppKit/CPApplication.j | 4 +- AppKit/CPDocumentController.j | 94 +++++++++++++++++- AppKit/CPMenu.j | 16 +++ .../CPWindowStandardCloseButtonUnsaved.png | Bin 720 -> 757 bytes ...wStandardCloseButtonUnsavedHighlighted.png | Bin 716 -> 753 bytes 5 files changed, 111 insertions(+), 3 deletions(-) diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index c5033ed53..386c3d551 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -288,7 +288,9 @@ CPRunContinuesResponse = -1002; if (needsUntitled) [_documentController newDocument:self]; - + + [_documentController _updateRecentDocumentsMenu]; + [defaultCenter postNotificationName:CPApplicationDidFinishLaunchingNotification object:self]; diff --git a/AppKit/CPDocumentController.j b/AppKit/CPDocumentController.j index c392d172e..9431155fe 100644 --- a/AppKit/CPDocumentController.j +++ b/AppKit/CPDocumentController.j @@ -114,7 +114,7 @@ var CPSharedDocumentController = nil; [theDocument makeWindowControllers]; [theDocument showWindows]; } - + return theDocument; } @@ -145,10 +145,13 @@ var CPSharedDocumentController = nil; var type = [self typeForContentsOfURL:anAbsoluteURL error:anError]; result = [self makeDocumentWithContentsOfURL:anAbsoluteURL ofType:type delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:[CPDictionary dictionaryWithObject:shouldDisplay forKey:@"shouldDisplay"]]; + + if (result) + [self noteNewRecentDocument:result]; } else if (shouldDisplay) [result showWindows]; - + return result; } @@ -358,3 +361,90 @@ var CPSharedDocumentController = nil; } @end + +@implementation CPDocumentController (Recents) + +- (CPArray)recentDocumentURLs +{ + // FIXME move this to CP land + if (typeof window["cpRecentDocumentURLs"] === 'function') + return window.cpRecentDocumentURLs(); + + return []; +} + +- (void)clearRecentDocuments:(id)sender +{ + if (typeof window["cpClearRecentDocuments"] === 'function') + window.cpClearRecentDocuments(); + + [self _updateRecentDocumentsMenu]; +} + +- (void)noteNewRecentDocument:(CPDocument)aDocument +{ + [self noteNewRecentDocumentURL:[[aDocument fileURL] absoluteString]]; +} + +- (void)noteNewRecentDocumentURL:(CPString)aURL +{ + if (typeof window["cpNoteNewRecentDocumentURL"] === 'function') + window.cpNoteNewRecentDocumentURL(aURL); + + [self _updateRecentDocumentsMenu]; +} + +- (void)_removeAllRecentDocumentsFromMenu:(CPMenu)aMenu +{ + var items = [aMenu itemArray], + count = [items count]; + + while (count--) + { + var item = items[count]; + + if ([item action] === @selector(_openRecentDocument:)) + [aMenu removeItemAtIndex:count]; + } +} + +- (void)_updateRecentDocumentsMenu +{ + var menu = [[CPApp mainMenu] _menuWithName:@"_CPRecentDocumentsMenu"], + recentDocuments = [self recentDocumentURLs], + menuItems = [menu itemArray], + documentCount = [recentDocuments count], + menuItemCount = [menuItems count]; + + [self _removeAllRecentDocumentsFromMenu:menu]; + + if (menuItemCount) + { + if (!documentCount) + { + if ([menuItems[0] isSeparatorItem]) + [menu removeItemAtIndex:0]; + } + else + { + if (![menuItems[0] isSeparatorItem]) + [menu insertItem:[CPMenuItem separatorItem] atIndex:0]; + } + } + + while (documentCount--) + { + var path = recentDocuments[documentCount], + item = [[CPMenuItem alloc] initWithTitle:[path lastPathComponent] action:@selector(_openRecentDocument:) keyEquivalent:nil]; + + [item setTag:path]; + [menu insertItem:item atIndex:0]; + } +} + +- (void)_openRecentDocument:(id)sender +{ + [self openDocumentWithContentsOfURL:[sender tag] display:YES error:nil]; +} + +@end diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index ad0e2dad7..45845b168 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -865,6 +865,22 @@ var _CPMenuBarVisible = NO, } } +- (void)_menuWithName:(CPString)aName +{ + if (aName === _name) + return self; + + for (var i = 0, count = [_items count]; i < count; i++) + { + var menu = [[_items[i] submenu] _menuWithName:aName]; + + if (menu) + return menu; + } + + return nil; +} + @end diff --git a/AppKit/Resources/CPWindow/Standard/CPWindowStandardCloseButtonUnsaved.png b/AppKit/Resources/CPWindow/Standard/CPWindowStandardCloseButtonUnsaved.png index 2cb0e49295e36af48f14368fef07f3e21ab00452..9bd3566b10cd4a98535a069b570b4b87501c067e 100644 GIT binary patch delta 696 zcmV;p0!RJO1@#4xNq?6~L_t(|+H_J~OH@%5-RIu9U*kB#I1>(PCJg07363KYlMw!Z z{(#YIPl59+A}At0_@ML)eDMb)^kff#VT?8oVx(C{mSciNXzI+p-h0~X;D{6*Sln~> zS!?fg_C8{4Y>et_baYgdhlkrYq#X9D)d#-k-9%hBjBUfVUw_>dVzPU3a(8@uT-G(( z6>(@`WaM$VT3tQ={ria?1f8a?YXJ6$;S3ybFB1qMAU2*)OcV}}kLQ@2G)M{$B0f-Ri8)6P_36a1$IjmT5{O z6jIf3N7($|0>}4#@=2L;lpiM^KT~((uA<83^722zkAEvG>Kp(!+|+c2I2@eDTUx#y z?d)VA4zZKZ#UgpGOX=QT?xCb@{{OzQL9uZ7ayn7gu=WfIes<<^FN&4QEuNKz1dZIx zz13Cvw6vtEJB~w*k%&r;aZ1|`pn(=wIBe|bSmbK!0sp`vCK8LqD49$uM59p^!x=c> zLIbUONPoO(Wjs76m!E!FTg&(-C+dY>UAT(g&=Bx6wo=*bGY%~<_Vfr_%jffG$YCUv z+P~J;M(3K=%vLS8S{0HLIf+CNPp5x%_V+Kw(&;(ozGPIUr>A`}H8rK|6$%CQs2Fz` zeT>_T<_iM{jQ5Np;~nG2%*>2e@n=@`Owf1h)0YM7s(nf5}d#xgy=kT eB{b0f5nuor*%G{tZ>i7#0000{5fJt3T_4*)Eq^SA;?WQ6}YMY zpxrFm=`sieUAb`Ktl9}e`xa41l;AePjrl7_u|+b&Oa(zRI_k4?E2&(MP$;Z)jxm)= z>10!-Qh7KYk6&F~UENm{#cMK|6r<6oVA~6^+h=EIk05@W&1R1qjfO^^0f{7=tJUfu z5?)oT3%jB$@S%q53hWwlx<&1Q42Uax;ZMRjXyOAx3m3Rs?BL*FKYx)(v`yHzwcG8dIH$@g1O+0Ih}hZL5hx%=qmk(KdhCT1o=&GKIS@Fc zfCqs)B-(5?fo4f^G#cGB7m2hl27|%I6*=Vc?>g*x_3BL6-Q5*`uRtIm_w+nC^B{bU z0#*bx{p_?%oBvyS9*)D?u}VMN+uIjtpsYZ&TCIPG-G6R(v(H?Y%XPsxdvM|PdOx3> zoW!`vMp1y>4u`|iQK!=p!{Jc4-R_MDIpAJW;9D#fdyV_u<6KYxj%3$yy|TL9Zf8X) z&g;YxHFC(Mz&QvF1n#2JKJ9UE);6U8zj;G`0xV{CX>lyjA|72<%Ise zcoc|e!GB<|?f3hiA@maXVstnhBAHBHQqAdfo?>%}_`L_t(|+GJASOH*MO{?6Gs$IXpNZD1Lt82KwTBa6~tn-lC} zUFuB)6Eua5(RFm)A7IwQ8E0&1Pc)k|gmi#9@_6eTKqVj1N zIH2)OtL6waAI@W@k?rynkO@Jp66M0oUpE>bx1DaJIR5 zYkO_2O?1eTL8)A3SA0Gm;wp)A6r__f64O9~C}8mGW-$2jc`nyN5zFXMOJ`i4n`5gp zGhBdh9rR~l4ntbs@;Y?@eG;z~}Z2|pu|NV!CtsUQ@rXEYi$;w|wwh?)Otsnu#8lV$m8u~=O7dcCKU$>bU3z9Er4VyY8aQ!bZt)9Li};c&21 zMO0;yBylMJh#?2L;D9R}k4K@?>9`w>#wS4#BvBL@fa>T1hluEc?e}{Q;`~XaQja5% z$Ot1C`u+Y3N`ID6MWfO1YN1ewdA(jvCQlf(&&f0%BX1;dNFWCR>vFjaD=kBS0xTMh zp3RNNZ5lu^aCK>h$Uut(G;LOWn11?6mv)ODP zVzJne_IozUWHK?c+00=y8u^A$89B%W2V6b^;WN2>O^MoeyX~PBsjyB!IUrK}5Dte& zZnygy9Di`t^ZA@55{b>JlUt9+BU76X>E%hQ)ry;Jx7%fx%k?XnOulnC95;0Jp71@N z&&xtCm*Xv0t5yD}2=F36a1ky~4crpG5D%PDHLkV1hIoFi`*i From 84f131808d5caa62777c3626017697b5d832ff42 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Thu, 29 Oct 2009 00:53:13 -0700 Subject: [PATCH 47/58] Removed some remaining cell "influences" in nib2cib'ed cib. There are references to NSCells in the object graph which should be removed, their children promoted to their parent's children. Reviewed by me. --- Tools/nib2cib/NSCell.j | 1 + Tools/nib2cib/NSIBObjectData.j | 64 ++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/Tools/nib2cib/NSCell.j b/Tools/nib2cib/NSCell.j index a25a3f25f..604afeadf 100644 --- a/Tools/nib2cib/NSCell.j +++ b/Tools/nib2cib/NSCell.j @@ -27,6 +27,7 @@ @import "NSFont.j" + @implementation NSCell : CPObject { int _state @accessors(readonly, getter=state); diff --git a/Tools/nib2cib/NSIBObjectData.j b/Tools/nib2cib/NSIBObjectData.j index 6c7214bbb..e19f4ce78 100644 --- a/Tools/nib2cib/NSIBObjectData.j +++ b/Tools/nib2cib/NSIBObjectData.j @@ -58,6 +58,8 @@ _objectsKeys = [aCoder decodeObjectForKey:@"NSObjectsKeys"]; _objectsValues = [aCoder decodeObjectForKey:@"NSObjectsValues"]; + [self removeCellsFromObjectGraph]; + //_oidKeys = [aCoder decodeObjectForKey:@"NSOidsKeys"]; //_oidValues = [aCoder decodeObjectForKey:@"NSOidsValues"]; @@ -68,6 +70,68 @@ return self; } +- (void)removeCellsFromObjectGraph +{ + // FIXME: Remove from top level objects and connections? + + // Most cell references should be naturally removed by the fact that we don't manually + // encode them anywhere, however, they remain in our object graph. For each cell found, + // take its children and promote them to our parent object's children. + var count = _objectsKeys.length, + parentForCellUIDs = { }, + promotedChildrenForCellUIDs = { }; + + while (count--) + { + var child = _objectsKeys[count]; + + if (!child) + continue; + + var parent = _objectsValues[count]; + + // If this object is a cell, remember it's parent. + if ([child isKindOfClass:[NSCell class]]) + { + parentForCellUIDs[[child UID]] = parent; + continue; + } + + // If parent also isn't a cell, we don't care about it. + if (![parent isKindOfClass:[NSCell class]]) + continue; + + // Remember this child for later promotion. + var parentUID = [parent UID], + children = promotedChildrenForCellUIDs[parentUID]; + + if (!children) + { + children = []; + promotedChildrenForCellUIDs[parentUID] = children; + } + + children.push(child); + + _objectsKeys.splice(count, 1); + _objectsValues.splice(count, 1); + } + + for (var cellUID in promotedChildrenForCellUIDs) + if (promotedChildrenForCellUIDs.hasOwnProperty(cellUID)) + { + var children = promotedChildrenForCellUIDs[cellUID], + parent = parentForCellUIDs[cellUID]; + + children.forEach(function(aChild) + { + CPLog.warn("Promoted " + aChild + " to child of " + parent); + _objectsKeys.push(aChild); + _objectsValues.push(parent); + }); + } +} + @end @implementation NSIBObjectData : _CPCibObjectData From 499d2d93d569fe05396ce6e09238a249d744f831 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Thu, 29 Oct 2009 16:25:05 -0700 Subject: [PATCH 48/58] Added import just in case. Reviewed by me. --- Tools/nib2cib/NSIBObjectData.j | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tools/nib2cib/NSIBObjectData.j b/Tools/nib2cib/NSIBObjectData.j index e19f4ce78..26d2e5481 100644 --- a/Tools/nib2cib/NSIBObjectData.j +++ b/Tools/nib2cib/NSIBObjectData.j @@ -22,6 +22,8 @@ @import +@import "NSCell.j" + @implementation _CPCibObjectData (NSCoding) From bcd8c72ae4c1407d6aacefca867670d77338575e Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Fri, 30 Oct 2009 10:53:47 -0700 Subject: [PATCH 49/58] Add an unsaved state affordance to the close button on standard windows. --- AppKit/CPWindow/CPWindow.j | 2 ++ AppKit/CPWindow/_CPStandardWindowView.j | 45 +++++++++++++++++++------ AppKit/CPWindow/_CPWindowView.j | 4 +++ AppKit/CPWindowController.j | 21 ++++++++++++ 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 59c0c3501..32509b2d3 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1510,6 +1510,8 @@ CPTexturedBackgroundWindowMask _isDocumentEdited = isDocumentEdited; [CPMenu _setMenuBarIconImageAlphaValue:_isDocumentEdited ? 0.5 : 1.0]; + + [_windowView setDocumentEdited:isDocumentEdited]; } /*! diff --git a/AppKit/CPWindow/_CPStandardWindowView.j b/AppKit/CPWindow/_CPStandardWindowView.j index 5b100a2cc..8ea33a72e 100644 --- a/AppKit/CPWindow/_CPStandardWindowView.j +++ b/AppKit/CPWindow/_CPStandardWindowView.j @@ -94,13 +94,15 @@ var _CPTexturedWindowHeadGradientColor = nil, @end -var _CPStandardWindowViewBodyBackgroundColor = nil, - _CPStandardWindowViewDividerBackgroundColor = nil, - _CPStandardWindowViewTitleBackgroundColor = nil, - _CPStandardWindowViewCloseButtonImage = nil, - _CPStandardWindowViewCloseButtonHighlightedImage = nil, - _CPStandardWindowViewMinimizeButtonImage = nil, - _CPStandardWindowViewMinimizeButtonHighlightedImage = nil; +var _CPStandardWindowViewBodyBackgroundColor = nil, + _CPStandardWindowViewDividerBackgroundColor = nil, + _CPStandardWindowViewTitleBackgroundColor = nil, + _CPStandardWindowViewCloseButtonImage = nil, + _CPStandardWindowViewCloseButtonHighlightedImage = nil, + _CPStandardWindowViewCloseButtonUnsavedImage = nil, + _CPStandardWindowViewCloseButtonUnsavedHighlightedImage = nil, + _CPStandardWindowViewMinimizeButtonImage = nil, + _CPStandardWindowViewMinimizeButtonHighlightedImage = nil; var STANDARD_GRADIENT_HEIGHT = 41.0; STANDARD_TITLEBAR_HEIGHT = 25.0; @@ -115,6 +117,8 @@ var STANDARD_GRADIENT_HEIGHT = 41.0; CPTextField _titleField; CPButton _closeButton; CPButton _minimizeButton; + + BOOL _isDocumentEdited; } + (CPColor)bodyBackgroundColor @@ -262,14 +266,14 @@ var STANDARD_GRADIENT_HEIGHT = 41.0; _CPStandardWindowViewCloseButtonImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButton.png"] size:CGSizeMake(16.0, 16.0)]; _CPStandardWindowViewCloseButtonHighlightedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButtonHighlighted.png"] size:CGSizeMake(16.0, 16.0)]; + _CPStandardWindowViewCloseButtonUnsavedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButtonUnsaved.png"] size:CGSizeMake(16.0, 16.0)]; + _CPStandardWindowViewCloseButtonUnsavedHighlightedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButtonUnsavedHighlighted.png"] size:CGSizeMake(16.0, 16.0)]; } _closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 7.0, 16.0, 16.0)]; [_closeButton setBordered:NO]; - - [_closeButton setImage:_CPStandardWindowViewCloseButtonImage]; - [_closeButton setAlternateImage:_CPStandardWindowViewCloseButtonHighlightedImage]; + [self _updateCloseButton]; [self addSubview:_closeButton]; } @@ -367,6 +371,27 @@ var STANDARD_GRADIENT_HEIGHT = 41.0; } } */ + +- (void)_updateCloseButton +{ + if (_isDocumentEdited) + { + [_closeButton setImage:_CPStandardWindowViewCloseButtonUnsavedImage]; + [_closeButton setAlternateImage:_CPStandardWindowViewCloseButtonUnsavedHighlightedImage]; + } + else + { + [_closeButton setImage:_CPStandardWindowViewCloseButtonImage]; + [_closeButton setAlternateImage:_CPStandardWindowViewCloseButtonHighlightedImage]; + } +} + +- (void)setDocumentEdited:(BOOL)isEdited +{ + _isDocumentEdited = isEdited; + [self _updateCloseButton]; +} + - (void)setTitle:(CPString)aTitle { [_titleField setStringValue:aTitle]; diff --git a/AppKit/CPWindow/_CPWindowView.j b/AppKit/CPWindow/_CPWindowView.j index 5231016f6..0f878fd9a 100644 --- a/AppKit/CPWindow/_CPWindowView.j +++ b/AppKit/CPWindow/_CPWindowView.j @@ -88,6 +88,10 @@ var _CPWindowViewResizeIndicatorImage = nil; return self; } +- (void)setDocumentEdited:(BOOL)isEdited +{ +} + - (void)setTitle:(CPString)aTitle { } diff --git a/AppKit/CPWindowController.j b/AppKit/CPWindowController.j index 5909e2d63..aaaf14291 100644 --- a/AppKit/CPWindowController.j +++ b/AppKit/CPWindowController.j @@ -399,6 +399,27 @@ */ - (void)setDocumentEdited:(BOOL)isEdited { + // we ignore this. in a multi-doc world, we base this flag on the logical OR + // of all the open documents edited state. so this is just a hint to re-check that state. + //[[self window] setDocumentEdited:isEdited]; + [self _synchronizeDocumentEditedState]; +} + +- (void)_synchronizeDocumentEditedState +{ + var docs = [self documents], + count = [docs count], + isEdited = NO; + + while (count--) + { + if ([docs[count] isDocumentEdited]) + { + isEdited = YES; + break; + } + } + [[self window] setDocumentEdited:isEdited]; } From 14ad8f6d6db356cc416e94706c32fcf89a810ff3 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Sat, 31 Oct 2009 18:32:58 -0700 Subject: [PATCH 50/58] Cleaned up key equivalent handling and added support for key equivalents to nib2cib. Reviewed by me. --- AppKit/CPApplication.j | 7 ++--- AppKit/CPCompatibility.j | 6 ++-- AppKit/CPEvent.j | 8 +++++ AppKit/CPMenuItem.j | 41 +++++++++++++++---------- AppKit/CPView.j | 13 ++++++++ AppKit/CPWindow/CPWindow.j | 15 +++++++-- Tools/nib2cib/NSEvent.j | 62 ++++++++++++++++++++++++++++++++++++++ Tools/nib2cib/NSMenuItem.j | 6 ++-- 8 files changed, 128 insertions(+), 30 deletions(-) create mode 100644 Tools/nib2cib/NSEvent.j diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index c5033ed53..cc6e44e4d 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -446,7 +446,7 @@ CPRunContinuesResponse = -1002; if ([_mainMenu performKeyEquivalent:anEvent]) return YES; - return NO; + return [[self keyWindow] performKeyEquivalent:anEvent]; } /*! @@ -458,10 +458,7 @@ CPRunContinuesResponse = -1002; _currentEvent = anEvent; // Check if this is a candidate for key equivalent... - if ([anEvent type] == CPKeyDown && - [anEvent modifierFlags] & (CPCommandKeyMask | CPControlKeyMask) && - [[anEvent characters] length] > 0 && - [self _handleKeyEquivalent:anEvent]) + if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent]) return; if (_eventListeners.length) diff --git a/AppKit/CPCompatibility.j b/AppKit/CPCompatibility.j index 2539b2ab1..b2636811d 100644 --- a/AppKit/CPCompatibility.j +++ b/AppKit/CPCompatibility.j @@ -179,7 +179,7 @@ function CPBrowserIsEngine(anEngine) if (USER_AGENT.indexOf("Mac") != -1) { CPPlatformActionKeyMask = CPCommandKeyMask; - + CPUndoKeyEquivalent = @"Z"; CPRedoKeyEquivalent = @"Z"; @@ -189,10 +189,10 @@ if (USER_AGENT.indexOf("Mac") != -1) else { CPPlatformActionKeyMask = CPControlKeyMask; - + CPUndoKeyEquivalent = @"Z"; CPRedoKeyEquivalent = @"Y"; - + CPUndoKeyEquivalentModifierMask = CPControlKeyMask; CPRedoKeyEquivalentModifierMask = CPControlKeyMask; } diff --git a/AppKit/CPEvent.j b/AppKit/CPEvent.j index eb942a79f..95993fb8a 100644 --- a/AppKit/CPEvent.j +++ b/AppKit/CPEvent.j @@ -515,6 +515,14 @@ var _CPEventPeriodicEventPeriod = 0, return _deltaZ; } +- (BOOL)_couldBeKeyEquivalent +{ + // FIXME: More cases? Space? + return _type === CPKeyDown && + _modifierFlags & (CPCommandKeyMask | CPControlKeyMask) && + [_characters length] > 0; +} + /*! Generates periodic events every \c aPeriod seconds. @param aDelay the number of seconds before the first event diff --git a/AppKit/CPMenuItem.j b/AppKit/CPMenuItem.j index 2a35aceb2..7306b8f49 100644 --- a/AppKit/CPMenuItem.j +++ b/AppKit/CPMenuItem.j @@ -744,26 +744,29 @@ CPControlKeyMask @end -var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey", +var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey", - CPMenuItemTitleKey = @"CPMenuItemTitleKey", - CPMenuItemTargetKey = @"CPMenuItemTargetKey", - CPMenuItemActionKey = @"CPMenuItemActionKey", + CPMenuItemTitleKey = @"CPMenuItemTitleKey", + CPMenuItemTargetKey = @"CPMenuItemTargetKey", + CPMenuItemActionKey = @"CPMenuItemActionKey", - CPMenuItemIsEnabledKey = @"CPMenuItemIsEnabledKey", - CPMenuItemIsHiddenKey = @"CPMenuItemIsHiddenKey", + CPMenuItemIsEnabledKey = @"CPMenuItemIsEnabledKey", + CPMenuItemIsHiddenKey = @"CPMenuItemIsHiddenKey", - CPMenuItemTagKey = @"CPMenuItemTagKey", - CPMenuItemStateKey = @"CPMenuItemStateKey", + CPMenuItemTagKey = @"CPMenuItemTagKey", + CPMenuItemStateKey = @"CPMenuItemStateKey", - CPMenuItemImageKey = @"CPMenuItemImageKey", - CPMenuItemAlternateImageKey = @"CPMenuItemAlternateImageKey", + CPMenuItemImageKey = @"CPMenuItemImageKey", + CPMenuItemAlternateImageKey = @"CPMenuItemAlternateImageKey", - CPMenuItemSubmenuKey = @"CPMenuItemSubmenuKey", - CPMenuItemMenuKey = @"CPMenuItemMenuKey", + CPMenuItemSubmenuKey = @"CPMenuItemSubmenuKey", + CPMenuItemMenuKey = @"CPMenuItemMenuKey", - CPMenuItemRepresentedObjectKey = @"CPMenuItemRepresentedObjectKey", - CPMenuItemViewKey = @"CPMenuItemViewKey"; + CPMenuItemKeyEquivalentKey = @"CPMenuItemKeyEquivalentKey", + CPMenuItemKeyEquivalentModifierMaskKey = @"CPMenuItemKeyEquivalentModifierMaskKey", + + CPMenuItemRepresentedObjectKey = @"CPMenuItemRepresentedObjectKey", + CPMenuItemViewKey = @"CPMenuItemViewKey"; #define DEFAULT_VALUE(aKey, aDefaultValue) [aCoder containsValueForKey:(aKey)] ? [aCoder decodeObjectForKey:(aKey)] : (aDefaultValue) #define ENCODE_IFNOT(aKey, aValue, aDefaultValue) if ((aValue) !== (aDefaultValue)) [aCoder encodeObject:(aValue) forKey:(aKey)]; @@ -804,8 +807,8 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey", _submenu = DEFAULT_VALUE(CPMenuItemSubmenuKey, nil); _menu = DEFAULT_VALUE(CPMenuItemMenuKey, nil); -// CPString _keyEquivalent; -// unsigned _keyEquivalentModifierMask; + _keyEquivalent = [aCoder decodeObjectForKey:CPMenuItemKeyEquivalentKey] || @""; + _keyEquivalentModifierMask = [aCoder decodeObjectForKey:CPMenuItemKeyEquivalentModifierMaskKey] || 0; // int _mnemonicLocation; @@ -847,6 +850,12 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey", ENCODE_IFNOT(CPMenuItemSubmenuKey, _submenu, nil); ENCODE_IFNOT(CPMenuItemMenuKey, _menu, nil); + if (_keyEquivalent && _keyEquivalent.length) + [aCoder encodeObject:_keyEquivalent forKey:CPMenuItemKeyEquivalentKey]; + + if (_keyEquivalentModifierMask) + [aCoder encodeObject:_keyEquivalentModifierMask forKey:CPMenuItemKeyEquivalentModifierMaskKey]; + ENCODE_IFNOT(CPMenuItemRepresentedObjectKey, _representedObject, nil); ENCODE_IFNOT(CPMenuItemViewKey, _view, nil); } diff --git a/AppKit/CPView.j b/AppKit/CPView.j index c0e7a5157..c53892f76 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -1861,6 +1861,19 @@ setBoundsOrigin: @implementation CPView (KeyView) +- (BOOL)performKeyEquivalent:(CPEvent)anEvent +{ + var subviews = [self subviews], + count = [subviews count]; + + // Is reverse iteration correct here? It matches the other (correct) code like hit testing. + while (count--) + if ([subviews[count] performKeyEquivalent:anEvent]) + return YES; + + return NO; +} + - (BOOL)canBecomeKeyView { return [self acceptsFirstResponder] && ![self isHiddenOrHasHiddenAncestor]; diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 32509b2d3..fc82ea3a8 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1996,10 +1996,19 @@ CPTexturedBackgroundWindowMask return NO; } -- (void)keyDown:(CPEvent)event +- (void)performKeyEquivalent:(CPEvent)anEvent { - if (![self performKeyEquivalent:event]) - [self interpretKeyEvents:[event]]; + // FIXME: should we be starting at the root, in other words _windowView? + // The evidence seems to point to no... + return [[self contentView] performKeyEquivalent:anEvent]; +} + +- (void)keyDown:(CPEvent)anEvent +{ + // It's not clear why we do performKeyEquivalent again here... + // Perhaps to allow something to happen between sendEvent: and keyDown:? + if (![anEvent _couldBeKeyEquivalent] || ![self performKeyEquivalent:anEvent]) + [self interpretKeyEvents:[anEvent]]; } - (void)insertNewline:(id)sender diff --git a/Tools/nib2cib/NSEvent.j b/Tools/nib2cib/NSEvent.j new file mode 100644 index 000000000..d0d7e53d4 --- /dev/null +++ b/Tools/nib2cib/NSEvent.j @@ -0,0 +1,62 @@ +/* + * NSEvent.j + * nib2cib + * + * Created by Francisco Tolmasky. + * Copyright 2009, 280 North, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +NSAlphaShiftKeyMask = 1 << 16; +NSShiftKeyMask = 1 << 17; +NSControlKeyMask = 1 << 18; +NSAlternateKeyMask = 1 << 19; +NSCommandKeyMask = 1 << 20; +NSNumericPadKeyMask = 1 << 21; +NSHelpKeyMask = 1 << 22; +NSFunctionKeyMask = 1 << 23; +NSDeviceIndependentModifierFlagsMask = 0xffff0000; + +function CP_NSMapKeyMask(anNSKeyMask) +{ + var keyMask = 0; + + if (anNSKeyMask & NSAlphaShiftKeyMask) + keyMask |= CPAlphaShiftKeyMask; + + if (anNSKeyMask & NSShiftKeyMask) + keyMask |= CPShiftKeyMask; + + if (anNSKeyMask & NSControlKeyMask) + keyMask |= CPControlKeyMask; + + if (anNSKeyMask & NSAlternateKeyMask) + keyMask |= CPAlternateKeyMask; + + if (anNSKeyMask & NSCommandKeyMask) + keyMask |= CPCommandKeyMask; + + if (anNSKeyMask & NSNumericPadKeyMask) + keyMask |= CPNumericPadKeyMask; + + if (anNSKeyMask & NSHelpKeyMask) + keyMask |= CPHelpKeyMask; + + if (aKeyMask & NSFunctionKeyMask) + keyMask |= CPFunctionKeyMask; + + return keyMask; +} diff --git a/Tools/nib2cib/NSMenuItem.j b/Tools/nib2cib/NSMenuItem.j index 56ed373a2..245e867bf 100644 --- a/Tools/nib2cib/NSMenuItem.j +++ b/Tools/nib2cib/NSMenuItem.j @@ -57,9 +57,9 @@ _submenu = [aCoder decodeObjectForKey:"NSSubmenu"]; _menu = [aCoder decodeObjectForKey:"NSMenu"]; -// _keyEquivalent = [aCoder decodeObjectForKey:"NSKeyEquiv"]; -// _keyEquivalentModifierMask = [aCoder decodeObjectForKey:"NSKeyEquivModMask"]; - + _keyEquivalent = [aCoder decodeObjectForKey:"NSKeyEquiv"]; + _keyEquivalentModifierMask = CP_NSMapKeyMask([aCoder decodeObjectForKey:"NSKeyEquivModMask"]); + // _mnemonicLocation = [aCoder decodeObjectForKey:"NSMnemonicLoc"]; // _isAlternate = [aCoder decodeBoolForKey:"NSIsAlternate"]; From 874584310536f1bcc94415d4859c6c4556918eb9 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Sun, 1 Nov 2009 11:21:34 -0800 Subject: [PATCH 51/58] Change method name --- AppKit/CPDocumentController.j | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AppKit/CPDocumentController.j b/AppKit/CPDocumentController.j index 9431155fe..1e6917315 100644 --- a/AppKit/CPDocumentController.j +++ b/AppKit/CPDocumentController.j @@ -388,8 +388,8 @@ var CPSharedDocumentController = nil; - (void)noteNewRecentDocumentURL:(CPString)aURL { - if (typeof window["cpNoteNewRecentDocumentURL"] === 'function') - window.cpNoteNewRecentDocumentURL(aURL); + if (typeof window["cpNoteNewRecentDocumentPath"] === 'function') + window.cpNoteNewRecentDocumentPath(aURL); [self _updateRecentDocumentsMenu]; } From 2355cf4f6ce991b6122b37c89f38b965a724e14b Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Sun, 1 Nov 2009 13:05:49 -0800 Subject: [PATCH 52/58] Fixed performKeyEquivalent: order (execute on view hierarchy first, then menus). Reviewed by me. --- AppKit/CPApplication.j | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 6de3c808d..a567a454c 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -445,10 +445,8 @@ CPRunContinuesResponse = -1002; /* @ignore */ - (BOOL)_handleKeyEquivalent:(CPEvent)anEvent { - if ([_mainMenu performKeyEquivalent:anEvent]) - return YES; - - return [[self keyWindow] performKeyEquivalent:anEvent]; + return [[self keyWindow] performKeyEquivalent:anEvent] || + [_mainMenu performKeyEquivalent:anEvent]; } /*! From cba546880bb9204f2d6022581026cfd81b8bb4ab Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Sun, 1 Nov 2009 14:23:48 -0800 Subject: [PATCH 53/58] Added some missing import statements. Reviewed by me. --- Tools/nib2cib/NSAppKit.j | 1 + Tools/nib2cib/NSMenuItem.j | 1 + 2 files changed, 2 insertions(+) diff --git a/Tools/nib2cib/NSAppKit.j b/Tools/nib2cib/NSAppKit.j index a18c503d8..1852ebf55 100644 --- a/Tools/nib2cib/NSAppKit.j +++ b/Tools/nib2cib/NSAppKit.j @@ -32,6 +32,7 @@ @import "NSCustomObject.j" @import "NSCustomResource.j" @import "NSCustomView.j" +@import "NSEvent.j" @import "NSFont.j" @import "NSIBObjectData.j" @import "NSImageView.j" diff --git a/Tools/nib2cib/NSMenuItem.j b/Tools/nib2cib/NSMenuItem.j index 245e867bf..9630cf35f 100644 --- a/Tools/nib2cib/NSMenuItem.j +++ b/Tools/nib2cib/NSMenuItem.j @@ -22,6 +22,7 @@ @import +@import "NSEvent.j" @import "NSMenu.j" From 1ceeec8b5b6aa187cc5a2bf410a5827dd687e293 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Sun, 1 Nov 2009 15:05:22 -0800 Subject: [PATCH 54/58] Fixed typo in NSEvent.j. Reviewed by me. --- Tools/nib2cib/NSEvent.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/nib2cib/NSEvent.j b/Tools/nib2cib/NSEvent.j index d0d7e53d4..f669a2ed4 100644 --- a/Tools/nib2cib/NSEvent.j +++ b/Tools/nib2cib/NSEvent.j @@ -55,7 +55,7 @@ function CP_NSMapKeyMask(anNSKeyMask) if (anNSKeyMask & NSHelpKeyMask) keyMask |= CPHelpKeyMask; - if (aKeyMask & NSFunctionKeyMask) + if (anNSKeyMask & NSFunctionKeyMask) keyMask |= CPFunctionKeyMask; return keyMask; From eeae653c9416d2a616c958f1c1b47715765d6573 Mon Sep 17 00:00:00 2001 From: saikat Date: Mon, 2 Nov 2009 00:25:30 -0800 Subject: [PATCH 55/58] Made secure text fields have the right number of characters when focus is taken away from them. Closes issue #318. --- AppKit/CPTextField.j | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 7c748dcd9..926810c36 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -978,7 +978,8 @@ var secureStringForString = function(aString) // This is true for when aString === "" and null/undefined. if (!aString) return ""; - return Array(aString.length).join(CPSecureTextFieldCharacter); + + return Array(aString.length+1).join(CPSecureTextFieldCharacter); } From e8b1ff88461f8b4eb303e5435079f00b40159af2 Mon Sep 17 00:00:00 2001 From: Tom Robinson Date: Mon, 2 Nov 2009 00:37:40 -0800 Subject: [PATCH 56/58] Another Array().join() trick off-by-one bug. --- Objective-J/utilities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objective-J/utilities.js b/Objective-J/utilities.js index 31c18333b..f4315bf0d 100644 --- a/Objective-J/utilities.js +++ b/Objective-J/utilities.js @@ -168,7 +168,7 @@ var _sprintf_justify = function(sign, prefix, string, suffix, width, leftJustify var _sprintf_pad = function(n, ch) { - return Array(MAX(0,n)).join(ch); + return Array(MAX(0,n)+1).join(ch); } // Base64 encoding and decoding From 93c90274b5376b5c7ef0c9dea0c1ffcec4499ab7 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Mon, 2 Nov 2009 16:47:07 -0800 Subject: [PATCH 57/58] Updates for massaging a few key inputs. --- AppKit/CPApplication.j | 3 +++ AppKit/Platform/DOM/CPPlatformWindow+DOM.j | 23 +++++++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index a567a454c..b71659232 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -459,7 +459,10 @@ CPRunContinuesResponse = -1002; // Check if this is a candidate for key equivalent... if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent]) + { + [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO]; return; + } if (_eventListeners.length) { diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index 5733dac6c..5bd3393fd 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -448,14 +448,16 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; KeyCodesToPrevent[aDOMEvent.keyCode]; var isNativePasteEvent = NO, - isNativeCopyOrCutEvent = NO; + isNativeCopyOrCutEvent = NO, + overrideCharacters = nil; switch (aDOMEvent.type) { case "keydown": // Grab and store the keycode now since it is correct and consistent at this point. _keyCode = aDOMEvent.keyCode; - + var characters = String.fromCharCode(_keyCode).toLowerCase(); + overrideCharacters = modifierFlags & CPShiftKeyMask ? characters.toUpperCase() : characters; // If this could be a native PASTE event, then we need to further examine it before // sending a CPEvent. Select our element to see if anything gets pasted in it. @@ -474,7 +476,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; // can capture our internal Cappuccino pasteboard. else if ((characters == "c" || characters == "x") && (modifierFlags & CPPlatformActionKeyMask)) isNativeCopyOrCutEvent = YES; - + // Also, certain browsers (IE and Safari), have broken keyboard supportwhere they don't send keypresses for certain events. // So, allow the keypress event to handle the event if we are not a browser with broken (remedial) key support... else if (!CPFeatureIsCompatible(CPJavascriptRemedialKeySupport)) @@ -487,6 +489,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; // If this is in fact our broke state, continue to keypress and send the keydown. case "keypress": // If the source of this event is our pasteboard element, then simply let it continue // as normal, so that the paste event can successfully complete. + if ((aDOMEvent.target || aDOMEvent.srcElement) == _DOMPasteboardElement) return; @@ -495,20 +498,22 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; isARepeat = (_charCodes[keyCode] != nil); _charCodes[keyCode] = charCode; - - var characters = String.fromCharCode(charCode), + + var characters = overrideCharacters || String.fromCharCode(charCode), charactersIgnoringModifiers = characters.toLowerCase(); - + + // Safari won't send proper capitalization during cmd-key events + if (!overrideCharacters && (modifierFlags & CPCommandKeyMask) && (modifierFlags & CPShiftKeyMask)) + characters = characters.toUpperCase(); + event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags timestamp:timestamp windowNumber:windowNumber context:nil characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:isARepeat keyCode:keyCode]; - + if (isNativePasteEvent) { _pasteboardKeyDownEvent = event; - window.setNativeTimeout(function () { [self _checkPasteboardElement] }, 0); - return; } From 95c340164097a83417350458373920fcca896f67 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 4 Nov 2009 14:23:30 -0800 Subject: [PATCH 58/58] Fix some old calls to _bridgeMouseEvent: which were not updated --- AppKit/Platform/DOM/CPPlatformWindow+DOM.j | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index 5bd3393fd..84daf8745 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -715,7 +715,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; newEvent.preventDefault = function(){if(aDOMEvent.preventDefault) aDOMEvent.preventDefault()}; newEvent.stopPropagation = function(){if(aDOMEvent.stopPropagation) aDOMEvent.stopPropagation()}; - [self _bridgeMouseEvent:newEvent]; + [self mouseEvent:newEvent]; return; } @@ -738,10 +738,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; if (type === @"dblclick") { _overriddenEventType = CPDOMEventMouseDown; - [self _bridgeMouseEvent:aDOMEvent]; + [self mouseEvent:aDOMEvent]; _overriddenEventType = CPDOMEventMouseUp; - [self _bridgeMouseEvent:aDOMEvent]; + [self mouseEvent:aDOMEvent]; _overriddenEventType = nil;