diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index de8572111..012cc2ffb 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -476,6 +476,11 @@ CPRunContinuesResponse = -1002; _mainMenu = aMenu; } +- (void)orderFrontColorPanel:(id)aSender +{ + [[CPColorPanel sharedColorPanel] orderFront:self]; +} + - (void)orderFrontStandardAboutPanel:(id)aSender { [self orderFrontStandardAboutPanelWithOptions:nil]; diff --git a/AppKit/CPPopUpButton.j b/AppKit/CPPopUpButton.j index eeaa785b7..acaecb870 100644 --- a/AppKit/CPPopUpButton.j +++ b/AppKit/CPPopUpButton.j @@ -502,7 +502,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); { if ([self title] === aTitle) return; - + if ([self pullsDown]) { var items = [_menu itemArray]; diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j index 06588e24f..f5ecf0d27 100644 --- a/AppKit/Themes/Aristo/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo/ThemeDescriptors.j @@ -10,7 +10,7 @@ @import -@implementation AristoThemeDescriptor : CPObject +@implementation AristoThemeDescriptor : BKThemeDescriptor { } @@ -19,6 +19,137 @@ return @"Aristo"; } ++ (CPButton)button +{ + var button = [[CPButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 24.0)], + + bezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-right.png" size:CGSizeMake(4.0, 24.0)] + ] + isVertical:NO]], + + highlightedBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)] + ] + isVertical:NO]], + + defaultBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"default-button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"default-button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"default-button-bezel-right.png" size:CGSizeMake(4.0, 24.0)] + ] + isVertical:NO]], + + defaultHighlightedBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)] + ] + isVertical:NO]]; + + [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:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateBordered]; + [button setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"]; + + [button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; + [button setValue:highlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted]; + [button setValue:CGInsetMake(0.0, 5.0, 0.0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; + + [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:CGSizeMake(0.0, 24.0) forThemeAttribute:@"min-size"]; + [button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"]; + + return button; +} + ++ (CPButton)themedStandardButton +{ + var button = [self button]; + + [button setTitle:@"Cancel"]; + + return button; +} + ++ (CPButton)themedDefaultButton +{ + var button = [self button]; + + [button setTitle:@"OK"]; + [button setDefaultButton:YES]; + + return button; +} + ++ (CPPopUpButton)themedPopUpButton +{ + var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:NO], + color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"popup-bezel-right.png" size:CGSizeMake(27.0, 24.0)] + ] + isVertical:NO]]; + + [button setTitle:@"Pop Up"]; + + [button setValue:color forThemeAttribute:@"bezel-color" inState: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"]; + [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"]; + [button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"]; + + [button setValue:CGSizeMake(32.0, 24.0) forThemeAttribute:@"min-size"]; + [button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"]; + + [button addItemWithTitle:@"item"]; + + return button; +} + ++ (CPPopUpButton)themedPullDownMenu +{ + var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:YES], + color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"popup-bezel-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: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"]; + [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"]; + [button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"]; + + [button setValue:CGSizeMake(32.0, 24.0) forThemeAttribute:@"min-size"]; + [button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"]; + + [button addItemWithTitle:@"item"]; + + return button; +} + + (CPScroller)themedVerticalScroller { var scroller = [[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, 17.0, 170.0)], @@ -69,11 +200,11 @@ { var scroller = [[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, 170.0, 17.0)], trackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-horizontal-track.png" size:CGSizeMake(1.0, 17.0)]), - disabledTrackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-vertical-track-disabled.png" size:CGSizeMake(17.0, 1.0)]); + disabledTrackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-horizontal-track-disabled.png" size:CGSizeMake(17.0, 1.0)]); [scroller setValue:19.0 forThemeAttribute:@"minimum-knob-length"]; [scroller setValue:CGInsetMake(2.0, 0.0, 0.0, 0.0) forThemeAttribute:@"knob-inset"]; - [scroller setValue:CGInsetMake(0.0, -9.0, 0.0, -11.0) forThemeAttribute:@"track-inset"]; + [scroller setValue:CGInsetMake(0.0, -10.0, 0.0, -11.0) forThemeAttribute:@"track-inset"]; [scroller setValue:trackColor forThemeAttribute:@"knob-slot-color"]; [scroller setValue:disabledTrackColor forThemeAttribute:@"knob-slot-color" inState:CPThemeStateDisabled]; @@ -200,65 +331,6 @@ return textfield; } -+ (CPButton)themedButton -{ - var button = [[CPButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 24.0)], - - bezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: - [ - [_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"button-bezel-right.png" size:CGSizeMake(4.0, 24.0)] - ] - isVertical:NO]], - - highlightedBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: - [ - [_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)] - ] - isVertical:NO]], - - defaultBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: - [ - [_CPCibCustomResource imageResourceWithName:"default-button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"default-button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"default-button-bezel-right.png" size:CGSizeMake(4.0, 24.0)] - ] - isVertical:NO]], - - defaultHighlightedBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: - [ - [_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)] - ] - isVertical:NO]]; - - - [button setTitle:@"Cancel"]; - - [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:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateBordered]; - [button setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"]; - - [button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; - [button setValue:highlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted]; - [button setValue:CGInsetMake(0.0, 5.0, 0.0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; - - [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:CGSizeMake(0.0, 24.0) forThemeAttribute:@"min-size"]; - [button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"]; - - return button; -} - + (CPRadioButton)themedRadioButton { var button = [[CPRadio alloc] initWithFrame:CGRectMake(0.0, 0.0, 120.0, 17.0)]; @@ -315,56 +387,6 @@ return button; } -+ (CPPopUpButton)themedPopUpButton -{ - var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:NO], - color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: - [ - [_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"popup-bezel-right.png" size:CGSizeMake(27.0, 24.0)] - ] - isVertical:NO]]; - - [button setTitle:@"Pop Up"]; - - [button setValue:color forThemeAttribute:@"bezel-color" inState: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"]; - [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"]; - [button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"]; - - [button addItemWithTitle:@"item"]; - - return button; -} - -+ (CPPopUpButton)themedPullDownMenu -{ - var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:YES], - color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: - [ - [_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"popup-bezel-right-pullsdown.png" size:CGSizeMake(27.0, 24.0)] - ] - isVertical:NO]]; - - [button setTitle:@"Pop Up"]; - - [button setValue:color forThemeAttribute:@"bezel-color" inState: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"]; - [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"]; - [button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"]; - - [button addItemWithTitle:@"item"]; - - return button; -} - + (CPPopUpButton)themedSegmentedControl { var segmentedControl = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 24.0)]; @@ -527,7 +549,7 @@ @end -@implementation AristoHUDThemeDescriptor : CPObject +@implementation AristoHUDThemeDescriptor : BKThemeDescriptor { } @@ -536,7 +558,7 @@ return @"Aristo-HUD"; } -+ (CPColor)themeShowcaseBackgroundColor ++ (CPColor)defaultShowcaseBackgroundColor { return [CPColor blackColor]; } diff --git a/AppKit/Tools/BlendKit/BKShowcaseController.j b/AppKit/Tools/BlendKit/BKShowcaseController.j index 4b5a15fa3..623aba85f 100644 --- a/AppKit/Tools/BlendKit/BKShowcaseController.j +++ b/AppKit/Tools/BlendKit/BKShowcaseController.j @@ -5,108 +5,344 @@ @import "BKUtilities.j" +var LEFT_PANEL_WIDTH = 176.0; + +var BKStateToolbarItemIdentifier = @"BKStateToolbarItemIdentifier", + BKBackgroundColorToolbarItemIdentifier = @"BKBackgroundColorToolbarItemIdentifier"; + @implementation BKShowcaseController : CPObject { + CPArray _themeDescriptorClasses; + + CPCollectionView _themesCollectionView; + CPCollectionView _themedObjectsCollectionView; } - (void)applicationDidFinishLaunching:(CPNotification)aNotification { + _themeDescriptorClasses = [BKThemeDescriptor allThemeDescriptorClasses]; + var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask], - contentView = [theWindow contentView], + toolbar = [[CPToolbar alloc] initWithIdentifier:@"Toolbar"]; + + [toolbar setDelegate:self]; + [theWindow setToolbar:toolbar]; + + var contentView = [theWindow contentView], bounds = [contentView bounds], - themeDescriptorClasses = BKThemeDescriptorClasses(); - - var tabView = [[CPTabView alloc] initWithFrame:bounds]; - - [tabView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; - - [contentView addSubview:tabView]; - - var index = 0, - count = [themeDescriptorClasses count]; - - for (; index < count; ++index) + splitView = [[CPSplitView alloc] initWithFrame:bounds]; + + [splitView setIsPaneSplitter:YES]; + [splitView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; + + [contentView addSubview:splitView]; + + // Left Pane + var label = [CPTextField labelWithTitle:@"THEMES"]; + + [label setFont:[CPFont boldSystemFontOfSize:11.0]]; + [label setTextColor:[CPColor colorWithCalibratedRed:92.0 / 255.0 green:110.0 / 255.0 blue:129.0 / 255.0 alpha:1.0]]; + [label setTextShadowColor:[CPColor colorWithCalibratedRed:225.0 / 255.0 green:255.0 / 255.0 blue:255.0 / 255.0 alpha:0.7]]; + [label setTextShadowOffset:CGSizeMake(0.0, 1.0)]; + [label sizeToFit]; + [label setFrameOrigin:CGPointMake(5.0, 2.0)]; + + var themeDescriptorItem = [[CPCollectionViewItem alloc] init]; + + [themeDescriptorItem setView:[[BKThemeDescriptorCell alloc] init]]; + + _themesCollectionView = [[CPCollectionView alloc] initWithFrame:CGRectMake(0.0, 0.0, LEFT_PANEL_WIDTH, CGRectGetHeight(bounds))]; + + [_themesCollectionView setDelegate:self]; + [_themesCollectionView setItemPrototype:themeDescriptorItem]; + [_themesCollectionView setMinItemSize:CGSizeMake(20.0, 36.0)]; + [_themesCollectionView setMaxItemSize:CGSizeMake(10000000.0, 36.0)]; + [_themesCollectionView setMaxNumberOfColumns:1]; + [_themesCollectionView setContent:_themeDescriptorClasses]; + [_themesCollectionView setAutoresizingMask:CPViewWidthSizable]; + [_themesCollectionView setVerticalMargin:0.0]; + [_themesCollectionView setSelectable:YES]; + [_themesCollectionView setFrameOrigin:CGPointMake(0.0, 20.0)]; + [_themesCollectionView setAutoresizingMask:CPViewWidthSizable]; + + var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, LEFT_PANEL_WIDTH, CGRectGetHeight(bounds))], + contentView = [scrollView contentView]; + + [scrollView setAutohidesScrollers:YES]; + [scrollView setDocumentView:_themesCollectionView]; + + [contentView setBackgroundColor:[CPColor colorWithRed:212.0 / 255.0 green:221.0 / 255.0 blue:230.0 / 255.0 alpha:1.0]]; + [contentView addSubview:label]; + + [splitView addSubview:scrollView]; + + // Right Pane + _themedObjectsCollectionView = [[CPCollectionView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds) - LEFT_PANEL_WIDTH - 1.0, 10.0)]; + + var collectionViewItem = [[CPCollectionViewItem alloc] init]; + + [collectionViewItem setView:[[BKShowcaseCell alloc] init]]; + + [_themedObjectsCollectionView setItemPrototype:collectionViewItem]; + [_themedObjectsCollectionView setVerticalMargin:20.0]; + [_themedObjectsCollectionView setAutoresizingMask:CPViewWidthSizable]; + + var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(LEFT_PANEL_WIDTH + 1.0, 0.0, CGRectGetWidth(bounds) - LEFT_PANEL_WIDTH - 1.0, CGRectGetHeight(bounds))]; + + [scrollView setHasHorizontalScroller:NO]; + [scrollView setAutohidesScrollers:YES]; + [scrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; + [scrollView setDocumentView:_themedObjectsCollectionView]; + + [splitView addSubview:scrollView]; + + [_themesCollectionView setSelectionIndexes:[CPIndexSet indexSetWithIndex:0]]; + + [theWindow setFullBridge:YES]; + [theWindow makeKeyAndOrderFront:self]; +} + +- (void)collectionViewDidChangeSelection:(CPCollectionView)aCollectionView +{ + var themeDescriptorClass = _themeDescriptorClasses[[[aCollectionView selectionIndexes] firstIndex]], + itemSize = [themeDescriptorClass itemSize]; + + // Make room for label and apply a minimum size. + itemSize.width = MAX(100.0, itemSize.width + 20.0); + itemSize.height = MAX(100.0, itemSize.height + 30.0); + + [_themedObjectsCollectionView setMinItemSize:itemSize]; + [_themedObjectsCollectionView setMaxItemSize:itemSize]; + + [_themedObjectsCollectionView setContent:[themeDescriptorClass themedObjectTemplates]]; + [BKShowcaseCell setBackgroundColor:[themeDescriptorClass showcaseBackgroundColor]]; +} + +- (CPArray)toolbarAllowedItemIdentifiers:(CPToolbar)aToolbar +{ + return [CPToolbarSpaceItemIdentifier, CPToolbarFlexibleSpaceItemIdentifier, BKBackgroundColorToolbarItemIdentifier, BKStateToolbarItemIdentifier]; +} + +- (CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)aToolbar +{ + return [CPToolbarFlexibleSpaceItemIdentifier, BKBackgroundColorToolbarItemIdentifier, BKStateToolbarItemIdentifier]; +} + +- (CPToolbarItem)toolbar:(CPToolbar)aToolbar itemForItemIdentifier:(CPString)anItemIdentifier willBeInsertedIntoToolbar:(BOOL)aFlag +{ + var toolbarItem = [[CPToolbarItem alloc] initWithItemIdentifier:anItemIdentifier]; + + [toolbarItem setTarget:self]; + + if (anItemIdentifier === BKStateToolbarItemIdentifier) { - var theClass = themeDescriptorClasses[index], - item = [[CPTabViewItem alloc] initWithIdentifier:[theClass themeName]], - templates = BKThemeObjectTemplatesForClass(theClass), - templatesCount = [templates count], - viewTemplates = [], - itemSize = CGSizeMake(0.0, 0.0); - - while (templatesCount--) - { - var template = templates[templatesCount], - object = [template valueForKey:@"themedObject"]; + var popUpButton = [CPPopUpButton buttonWithTitle:@"Enabled"]; - if ([object isKindOfClass:[CPView class]]) - { - var size = [object frame].size, - labelWidth = [[template valueForKey:@"label"] sizeWithFont:[CPFont boldSystemFontOfSize:12.0]].width + 20.0; + [popUpButton addItemWithTitle:@"Disabled"]; - if (size.width > itemSize.width) - itemSize.width = size.width; - - if (labelWidth > itemSize.width) - itemSize.width = labelWidth; - - if (size.height > itemSize.height) - itemSize.height = size.height; - - [viewTemplates addObject:template]; - } - } - - itemSize.width += 20.0; - itemSize.height += 30.0; + [toolbarItem setView:popUpButton]; + [toolbarItem setTarget:nil]; + [toolbarItem setAction:@selector(changeState:)]; + [toolbarItem setLabel:@"State"]; - var collectionView = [[CPCollectionView alloc] initWithFrame:CGRectMakeZero()], - collectionViewItem = [[CPCollectionViewItem alloc] init]; + var width = CGRectGetWidth([popUpButton frame]); - var backgroundColor = nil; + [toolbarItem setMinSize:CGSizeMake(width + 20.0, 32.0)]; + [toolbarItem setMaxSize:CGSizeMake(width + 20.0, 32.0)]; + } + + else if (BKBackgroundColorToolbarItemIdentifier) + { + var popUpButton = [CPPopUpButton buttonWithTitle:@"Light Checkers"]; - if ([theClass respondsToSelector:@selector(themeShowcaseBackgroundColor)]) - backgroundColor = [theClass themeShowcaseBackgroundColor]; + [popUpButton addItemWithTitle:@"Dark Checkers"]; + [popUpButton addItemWithTitle:@"Window Background Color"]; + [popUpButton addItemWithTitle:@"White"]; + [popUpButton addItemWithTitle:@"Black"]; + [popUpButton addItemWithTitle:@"More Choices..."]; - [collectionViewItem setView:[[BKShowcaseCell alloc] initWithShowcaseBackgroundColor:backgroundColor]]; + var itemArray = [popUpButton itemArray]; - [collectionView setItemPrototype:collectionViewItem]; - [collectionView setMinItemSize:itemSize]; - [collectionView setMaxItemSize:itemSize]; - [collectionView setVerticalMargin:5.0]; - [collectionView setContent:viewTemplates]; - - [item setLabel:[theClass themeName]]; - [item setView:collectionView]; + [itemArray[0] setRepresentedObject:[BKThemeDescriptor lightCheckersColor]]; + [itemArray[1] setRepresentedObject:[BKThemeDescriptor darkCheckersColor]]; + [itemArray[2] setRepresentedObject:[BKThemeDescriptor windowBackgroundColor]]; + [itemArray[3] setRepresentedObject:[CPColor whiteColor]]; + [itemArray[4] setRepresentedObject:[CPColor blackColor]]; - [tabView addTabViewItem:item]; + [toolbarItem setView:popUpButton]; + [toolbarItem setTarget:nil]; + [toolbarItem setAction:@selector(changeColor:)]; + [toolbarItem setLabel:@"Background Color"]; + + var width = CGRectGetWidth([popUpButton frame]); + + [toolbarItem setMinSize:CGSizeMake(width, 32.0)]; + [toolbarItem setMaxSize:CGSizeMake(width, 32.0)]; } - [theWindow orderFront:self]; + return toolbarItem; +} + +- (BKThemeDescriptor)selectedThemeDescriptor +{ + return _themeDescriptorClasses[[[_themesCollectionView selectionIndexes] firstIndex]]; +} + +- (void)changeState:(id)aSender +{ + var themedObjectTemplates = [[self selectedThemeDescriptor] themedObjectTemplates], + count = [themedObjectTemplates count]; + + while (count--) + { + var themedObject = [themedObjectTemplates[count] valueForKey:@"themedObject"]; + + if ([themedObject respondsToSelector:@selector(setEnabled:)]) + [themedObject setEnabled:[aSender title] === @"Enabled" ? YES : NO]; + } +} + +- (void)changeColor:(id)aSender +{ + var color = nil; + + if ([aSender isKindOfClass:[CPColorPanel class]]) + color = [aSender color]; + + else + { + if ([aSender titleOfSelectedItem] === @"More Choices...") + { + [aSender addItemWithTitle:@"Other"]; + [aSender selectItemWithTitle:@"Other"]; + + [CPApp orderFrontColorPanel:self]; + } + else + { + color = [[aSender selectedItem] representedObject]; + + [aSender removeItemWithTitle:@"Other"]; + } + } + + if (color) + { + [[self selectedThemeDescriptor] setShowcaseBackgroundColor:color]; + [BKShowcaseCell setBackgroundColor:color]; + } +} + +@end + +var SelectionColor = nil; + +@implementation BKThemeDescriptorCell : CPView +{ + CPTextField _label; +} + ++ (CPImage)selectionColor +{ + if (!SelectionColor) + SelectionColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[BKThemeDescriptorCell class]] pathForResource:@"selection.png"] size:CGSizeMake(1.0, 36.0)]]; + + return SelectionColor; +} + +- (void)setRepresentedObject:(id)aThemeDescriptor +{ + if (!_label) + { + _label = [CPTextField labelWithTitle:@"hello"]; + + [_label setFont:[CPFont systemFontOfSize:11.0]]; + [_label setFrame:CGRectMake(10.0, 0.0, CGRectGetWidth([self bounds]) - 20.0, CGRectGetHeight([self bounds]))]; + + [_label setVerticalAlignment:CPCenterVerticalTextAlignment]; + [_label setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; + + [self addSubview:_label]; + } + + [_label setStringValue:[aThemeDescriptor themeName] + " (" + [[aThemeDescriptor themedObjectTemplates] count] + ")"]; +} + +- (void)setSelected:(BOOL)isSelected +{ + [self setBackgroundColor:isSelected ? [[self class] selectionColor] : nil]; + + [_label setTextShadowOffset:isSelected ? CGSizeMake(0.0, 1.0) : CGSizeMakeZero()]; + [_label setTextShadowColor:isSelected ? [CPColor blackColor] : nil]; + [_label setFont:isSelected ? [CPFont boldSystemFontOfSize:11.0] : [CPFont systemFontOfSize:11.0]]; + [_label setTextColor:isSelected ? [CPColor whiteColor] : [CPColor blackColor]]; } @end +var ShowcaseCellBackgroundColor = nil; + +var BKShowcaseCellBackgroundColorDidChangeNotification = @"BKShowcaseCellBackgroundColorDidChangeNotification"; + @implementation BKShowcaseCell : CPView { - CPColor _showcaseBackgroundColor; CPView _backgroundView; CPView _view; CPTextField _label; } -- (id)initWithShowcaseBackgroundColor:(CPColor)aColor ++ (void)setBackgroundColor:(CPColor)aColor +{ + if (ShowcaseCellBackgroundColor === aColor) + return; + + ShowcaseCellBackgroundColor = aColor; + + [[CPNotificationCenter defaultCenter] + postNotificationName:BKShowcaseCellBackgroundColorDidChangeNotification + object:nil]; +} + ++ (CPColor)backgroundColor +{ + return ShowcaseCellBackgroundColor; +} + +- (id)init { self = [super init]; if (self) - _showcaseBackgroundColor = aColor; + [[CPNotificationCenter defaultCenter] + addObserver:self + selector:@selector(showcaseBackgroundDidChange:) + name:BKShowcaseCellBackgroundColorDidChangeNotification + object:nil]; return self; } +- (id)initWithCoder:(CPCoder)aCoder +{ + self = [super initWithCoder:aCoder]; + + if (self) + [[CPNotificationCenter defaultCenter] + addObserver:self + selector:@selector(showcaseBackgroundDidChange:) + name:BKShowcaseCellBackgroundColorDidChangeNotification + object:nil]; + + return self; +} + +- (void)showcaseBackgroundDidChange:(CPNotification)aNotification +{ + [_backgroundView setBackgroundColor:[BKShowcaseCell backgroundColor]]; +} + - (void)setSelected:(BOOL)isSelected { } @@ -116,26 +352,24 @@ if (!_label) { _label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()]; - + [_label setAlignment:CPCenterTextAlignment]; [_label setAutoresizingMask:CPViewMinYMargin | CPViewWidthSizable]; - [_label setFont:[CPFont boldSystemFontOfSize:12.0]]; - + [_label setFont:[CPFont boldSystemFontOfSize:11.0]]; + [self addSubview:_label]; } - + [_label setStringValue:[anObject valueForKey:@"label"]]; [_label sizeToFit]; - + [_label setFrame:CGRectMake(0.0, CGRectGetHeight([self bounds]) - CGRectGetHeight([_label frame]), CGRectGetWidth([self bounds]), CGRectGetHeight([_label frame]))]; - + if (!_backgroundView) { _backgroundView = [[CPView alloc] init]; - [_backgroundView setBackgroundColor:_showcaseBackgroundColor]; - [self addSubview:_backgroundView]; } @@ -153,23 +387,7 @@ (CGRectGetHeight([_backgroundView bounds]) - CGRectGetHeight([_view frame])) / 2.0)]; [_backgroundView addSubview:_view]; -} - -- (id)initWithCoder:(CPCoder)aCoder -{ - self = [super initWithCoder:aCoder]; - - if (self) - _showcaseBackgroundColor = [aCoder decodeObjectForKey:@"showcase-background-color"]; - - return self -} - -- (void)encodeWithCoder:(CPCoder)aCoder -{ - [super encodeWithCoder:aCoder]; - - [aCoder encodeObject:_showcaseBackgroundColor forKey:@"showcase-background-color"]; + [_backgroundView setBackgroundColor:[BKShowcaseCell backgroundColor]]; } @end diff --git a/AppKit/Tools/BlendKit/BKThemeDescriptor.j b/AppKit/Tools/BlendKit/BKThemeDescriptor.j new file mode 100644 index 000000000..fde4743fd --- /dev/null +++ b/AppKit/Tools/BlendKit/BKThemeDescriptor.j @@ -0,0 +1,200 @@ + +@import + + +var ItemSizes = { }, + ThemedObjects = { }, + BackgroundColors = { }, + + LightCheckersColor = nil, + DarkCheckersColor = nil, + WindowBackgroundColor = nil; + +@implementation BKThemeDescriptor : CPObject +{ +} + ++ (CPArray)allThemeDescriptorClasses +{ + // Grab Theme Descriptor Classes. + var themeDescriptorClasses = []; + + for (candidate in window) + { + var theClass = objj_getClass(candidate), + theClassName = class_getName(theClass); + + if (theClassName === "BKThemeDescriptor") + continue; + + var index = theClassName.indexOf("ThemeDescriptor"); + + if ((index >= 0) && (index === theClassName.length - "ThemeDescriptor".length)) + themeDescriptorClasses.push(theClass); + } + + [themeDescriptorClasses sortUsingSelector:@selector(compare:)]; + + return themeDescriptorClasses; +} + ++ (CPColor)lightCheckersColor +{ + if (!LightCheckersColor) + LightCheckersColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[BKThemeDescriptor class]] pathForResource:@"light-checkers.png"] size:CGSizeMake(12.0, 12.0)]]; + + return LightCheckersColor; +} + ++ (CPColor)darkCheckersColor +{ + if (!DarkCheckersColor) + DarkCheckersColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[BKThemeDescriptor class]] pathForResource:@"dark-checkers.png"] size:CGSizeMake(12.0, 12.0)]]; + + return DarkCheckersColor; +} + ++ (CPColor)windowBackgroundColor +{ + return [_CPStandardWindowView bodyBackgroundColor]; +} + ++ (CPColor)defaultShowcaseBackgroundColor +{ + return [self lightCheckersColor]; +} + ++ (CPColor)showcaseBackgroundColor +{ + var className = [self className]; + + if (!BackgroundColors[className]) + BackgroundColors[className] = [self defaultShowcaseBackgroundColor]; + + return BackgroundColors[className]; +} + ++ (void)setShowcaseBackgroundColor:(CPColor)aColor +{ + BackgroundColors[[self className]] = aColor; +} + ++ (CGSize)itemSize +{ + var className = [self className]; + + if (!ItemSizes[className]) + [self calculateThemedObjectTemplates]; + + return CGSizeMakeCopy(ItemSizes[className]); +} + ++ (CPArray)themedObjectTemplates +{ + var className = [self className]; + + if (!ThemedObjects[className]) + [self calculateThemedObjectTemplates]; + + return ThemedObjects[className]; +} + ++ (void)calculateThemedObjectTemplates +{ + var templates = [], + itemSize = CGSizeMake(0.0, 0.0), + methods = class_copyMethodList([self class].isa), + index = 0, + count = [methods count]; + + for (; index < count; ++index) + { + var method = methods[index], + selector = method_getName(method); + + if (selector.indexOf("themed") !== 0) + continue; + + var impl = method_getImplementation(method), + object = impl(self, selector); + + if (!object) + continue; + + var template = [[BKThemeObjectTemplate alloc] init]; + + [template setValue:object forKey:@"themedObject"]; + [template setValue:BKLabelFromIdentifier(selector) forKey:@"label"]; + + [templates addObject:template]; + + if ([object isKindOfClass:[CPView class]]) + { + var size = [object frame].size, + labelWidth = [[template valueForKey:@"label"] sizeWithFont:[CPFont boldSystemFontOfSize:12.0]].width + 20.0; + + if (size.width > itemSize.width) + itemSize.width = size.width; + + if (labelWidth > itemSize.width) + itemSize.width = labelWidth; + + if (size.height > itemSize.height) + itemSize.height = size.height; + } + } + + var className = [self className]; + + ItemSizes[className] = itemSize; + ThemedObjects[className] = templates; +} + ++ (int)compare:(BKThemeDescriptor)aThemeDescriptor +{ + return [[self themeName] compare:[aThemeDescriptor themeName]]; +} + +@end + +function BKLabelFromIdentifier(anIdentifier) +{ + var string = anIdentifier.substr("themed".length); + index = 0, + count = string.length, + label = "", + lastCapital = null, + isLeadingCapital = YES; + + for (; index < count; ++index) + { + var character = string.charAt(index), + isCapital = /^[A-Z]/.test(character); + + if (isCapital) + { + if (!isLeadingCapital) + { + if (lastCapital === null) + label += ' ' + character.toLowerCase(); + else + label += character; + } + + lastCapital = character; + } + else + { + if (isLeadingCapital && lastCapital !== null) + label += lastCapital; + + label += character; + + lastCapital = null; + isLeadingCapital = NO; + } + } + + return label; +} + diff --git a/AppKit/Tools/BlendKit/BKUtilities.j b/AppKit/Tools/BlendKit/BKUtilities.j index 42e3de0c2..ca8986cdd 100644 --- a/AppKit/Tools/BlendKit/BKUtilities.j +++ b/AppKit/Tools/BlendKit/BKUtilities.j @@ -52,94 +52,3 @@ } @end - -function BKThemeDescriptorClasses() -{ - // Grab Theme Descriptor Classes. - var themeDescriptorClasses = []; - - for (candidate in window) - { - var theClass = objj_getClass(candidate), - theClassName = class_getName(theClass), - index = theClassName.indexOf("ThemeDescriptor"); - - if ((index >= 0) && (index === theClassName.length - "ThemeDescriptor".length)) - themeDescriptorClasses.push(theClass); - } - - return themeDescriptorClasses; -} - -function BKThemeObjectTemplatesForClass(aClass) -{ - var templates = [], - methods = class_copyMethodList(aClass.isa), - count = [methods count]; - - while (count--) - { - var method = methods[count], - selector = method_getName(method); - - if (selector.indexOf("themed") === 0) - { - var impl = method_getImplementation(method), - object = impl(aClass, selector); - - if (object) - { - var template = [[BKThemeObjectTemplate alloc] init]; - - [template setValue:object forKey:@"themedObject"]; - [template setValue:BKLabelFromIdentifier(selector) forKey:@"label"]; - - [templates addObject:template]; - } - } - } - - return templates; -} - -function BKLabelFromIdentifier(anIdentifier) -{ - var string = anIdentifier.substr("themed".length); - index = 0, - count = string.length, - label = "", - lastCapital = null, - isLeadingCapital = YES; - - for (; index < count; ++index) - { - var character = string.charAt(index), - isCapital = /^[A-Z]/.test(character); - - if (isCapital) - { - if (!isLeadingCapital) - { - if (lastCapital === null) - label += ' ' + character.toLowerCase(); - else - label += character; - } - - lastCapital = character; - } - else - { - if (isLeadingCapital && lastCapital !== null) - label += lastCapital; - - label += character; - - lastCapital = null; - isLeadingCapital = NO; - } - } - - return label; -} - diff --git a/AppKit/Tools/BlendKit/BlendKit.j b/AppKit/Tools/BlendKit/BlendKit.j index 09821ddd7..9b0cf5122 100644 --- a/AppKit/Tools/BlendKit/BlendKit.j +++ b/AppKit/Tools/BlendKit/BlendKit.j @@ -1,3 +1,4 @@ @import "BKShowcaseController.j" +@import "BKThemeDescriptor.j" @import "BKUtilities.j" diff --git a/AppKit/Tools/BlendKit/Resources/dark-checkers.png b/AppKit/Tools/BlendKit/Resources/dark-checkers.png new file mode 100644 index 000000000..838362cf0 Binary files /dev/null and b/AppKit/Tools/BlendKit/Resources/dark-checkers.png differ diff --git a/AppKit/Tools/BlendKit/Resources/light-checkers.png b/AppKit/Tools/BlendKit/Resources/light-checkers.png new file mode 100644 index 000000000..83499084f Binary files /dev/null and b/AppKit/Tools/BlendKit/Resources/light-checkers.png differ diff --git a/AppKit/Tools/BlendKit/Resources/selection.png b/AppKit/Tools/BlendKit/Resources/selection.png new file mode 100644 index 000000000..aafc65dcf Binary files /dev/null and b/AppKit/Tools/BlendKit/Resources/selection.png differ