mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-26 05:27:03 +00:00
450 lines
15 KiB
Plaintext
450 lines
15 KiB
Plaintext
/*
|
|
* BKShowcaseController.j
|
|
* BlendKit
|
|
*
|
|
* 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
|
|
*/
|
|
|
|
@import <AppKit/CPTheme.j>
|
|
@import <AppKit/CPView.j>
|
|
|
|
|
|
var LEFT_PANEL_WIDTH = 176.0;
|
|
|
|
var BKLearnMoreToolbarItemIdentifier = @"BKLearnMoreToolbarItemIdentifier",
|
|
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],
|
|
toolbar = [[CPToolbar alloc] initWithIdentifier:@"Toolbar"];
|
|
|
|
[toolbar setDelegate:self];
|
|
[theWindow setToolbar:toolbar];
|
|
|
|
var contentView = [theWindow contentView],
|
|
bounds = [contentView bounds],
|
|
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:93.0 / 255.0 green:93.0 / 255.0 blue:93.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, 4.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]];
|
|
}
|
|
|
|
- (BOOL)hasLearnMoreURL
|
|
{
|
|
return [[CPBundle mainBundle] objectForInfoDictionaryKey:@"BKLearnMoreURL"];
|
|
}
|
|
|
|
- (CPArray)toolbarAllowedItemIdentifiers:(CPToolbar)aToolbar
|
|
{
|
|
return [BKLearnMoreToolbarItemIdentifier, CPToolbarSpaceItemIdentifier, CPToolbarFlexibleSpaceItemIdentifier, BKBackgroundColorToolbarItemIdentifier, BKStateToolbarItemIdentifier];
|
|
}
|
|
|
|
- (CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)aToolbar
|
|
{
|
|
var itemIdentifiers = [CPToolbarFlexibleSpaceItemIdentifier, BKBackgroundColorToolbarItemIdentifier, BKStateToolbarItemIdentifier];
|
|
|
|
if ([self hasLearnMoreURL])
|
|
itemIdentifiers = [BKLearnMoreToolbarItemIdentifier].concat(itemIdentifiers);
|
|
|
|
return itemIdentifiers;
|
|
}
|
|
|
|
- (CPToolbarItem)toolbar:(CPToolbar)aToolbar itemForItemIdentifier:(CPString)anItemIdentifier willBeInsertedIntoToolbar:(BOOL)aFlag
|
|
{
|
|
var toolbarItem = [[CPToolbarItem alloc] initWithItemIdentifier:anItemIdentifier];
|
|
|
|
[toolbarItem setTarget:self];
|
|
|
|
if (anItemIdentifier === BKStateToolbarItemIdentifier)
|
|
{
|
|
var popUpButton = [CPPopUpButton buttonWithTitle:@"Enabled"];
|
|
|
|
[popUpButton addItemWithTitle:@"Disabled"];
|
|
|
|
[toolbarItem setView:popUpButton];
|
|
[toolbarItem setTarget:nil];
|
|
[toolbarItem setAction:@selector(changeState:)];
|
|
[toolbarItem setLabel:@"State"];
|
|
|
|
var width = CGRectGetWidth([popUpButton frame]);
|
|
|
|
[toolbarItem setMinSize:CGSizeMake(width + 20.0, 24.0)];
|
|
[toolbarItem setMaxSize:CGSizeMake(width + 20.0, 24.0)];
|
|
}
|
|
|
|
else if (anItemIdentifier === BKBackgroundColorToolbarItemIdentifier)
|
|
{
|
|
var popUpButton = [CPPopUpButton buttonWithTitle:@"Window Background"];
|
|
|
|
[popUpButton addItemWithTitle:@"Light Checkers"];
|
|
[popUpButton addItemWithTitle:@"Dark Checkers"];
|
|
[popUpButton addItemWithTitle:@"White"];
|
|
[popUpButton addItemWithTitle:@"Black"];
|
|
[popUpButton addItemWithTitle:@"More Choices..."];
|
|
|
|
var itemArray = [popUpButton itemArray];
|
|
|
|
[itemArray[0] setRepresentedObject:[BKThemeDescriptor windowBackgroundColor]];
|
|
[itemArray[1] setRepresentedObject:[BKThemeDescriptor lightCheckersColor]];
|
|
[itemArray[2] setRepresentedObject:[BKThemeDescriptor darkCheckersColor]];
|
|
[itemArray[3] setRepresentedObject:[CPColor whiteColor]];
|
|
[itemArray[4] setRepresentedObject:[CPColor blackColor]];
|
|
|
|
[toolbarItem setView:popUpButton];
|
|
[toolbarItem setTarget:nil];
|
|
[toolbarItem setAction:@selector(changeColor:)];
|
|
[toolbarItem setLabel:@"Background Color"];
|
|
|
|
var width = CGRectGetWidth([popUpButton frame]);
|
|
|
|
[toolbarItem setMinSize:CGSizeMake(width, 24.0)];
|
|
[toolbarItem setMaxSize:CGSizeMake(width, 24.0)];
|
|
}
|
|
else if (anItemIdentifier === BKLearnMoreToolbarItemIdentifier)
|
|
{
|
|
var title = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"BKLearnMoreButtonTitle"];
|
|
|
|
if (!title)
|
|
title = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPBundleName"] || @"Home Page";
|
|
|
|
var button = [CPButton buttonWithTitle:title];
|
|
|
|
[button setDefaultButton:YES];
|
|
|
|
[toolbarItem setView:button];
|
|
[toolbarItem setLabel:@"Learn More"];
|
|
[toolbarItem setTarget:nil];
|
|
[toolbarItem setAction:@selector(learnMore:)];
|
|
|
|
var width = CGRectGetWidth([button frame]);
|
|
|
|
[toolbarItem setMinSize:CGSizeMake(width, 24.0)];
|
|
[toolbarItem setMaxSize:CGSizeMake(width, 24.0)];
|
|
}
|
|
|
|
return toolbarItem;
|
|
}
|
|
|
|
- (void)learnMore:(id)aSender
|
|
{
|
|
window.location.href = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"BKLearnMoreURL"];
|
|
}
|
|
|
|
- (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
|
|
{
|
|
CPView _backgroundView;
|
|
|
|
CPView _view;
|
|
CPTextField _label;
|
|
}
|
|
|
|
+ (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)
|
|
[[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
|
|
{
|
|
}
|
|
|
|
- (void)setRepresentedObject:(id)anObject
|
|
{
|
|
if (!_label)
|
|
{
|
|
_label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
|
|
|
[_label setAlignment:CPCenterTextAlignment];
|
|
[_label setAutoresizingMask:CPViewMinYMargin | CPViewWidthSizable];
|
|
[_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];
|
|
|
|
[self addSubview:_backgroundView];
|
|
}
|
|
|
|
[_backgroundView setFrame:CGRectMake(0.0, 0.0, CGRectGetWidth([self bounds]), CGRectGetMinY([_label frame]))];
|
|
[_backgroundView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
|
|
|
if (_view)
|
|
[_view removeFromSuperview];
|
|
|
|
_view = [anObject valueForKey:@"themedObject"];
|
|
|
|
[_view setTheme:nil];
|
|
[_view setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin | CPViewMinYMargin | CPViewMaxYMargin];
|
|
[_view setFrameOrigin:CGPointMake((CGRectGetWidth([_backgroundView bounds]) - CGRectGetWidth([_view frame])) / 2.0,
|
|
(CGRectGetHeight([_backgroundView bounds]) - CGRectGetHeight([_view frame])) / 2.0)];
|
|
|
|
[_backgroundView addSubview:_view];
|
|
[_backgroundView setBackgroundColor:[BKShowcaseCell backgroundColor]];
|
|
}
|
|
|
|
@end
|