88 CPToolbarDisplayMode _displayMode;
89 BOOL _showsBaselineSeparator;
90 BOOL _allowsUserCustomization;
105 CPArray _itemsSortedByVisibilityPriority;
124 var toolbarsSharingIdentifier = [CPToolbarsByIdentifier objectForKey:identifier];
126 if (!toolbarsSharingIdentifier)
128 toolbarsSharingIdentifier = []
129 [CPToolbarsByIdentifier setObject:toolbarsSharingIdentifier forKey:identifier];
132 [toolbarsSharingIdentifier addObject:toolbar];
140 + (id)_themeAttributes
145 forKeys:[@"content-inset", @"regular-size-height", @"small-size-height"]];
166 _identifier = anIdentifier;
171 [
CPToolbar _addToolbar:self forIdentifier:_identifier];
181 - (void)setDisplayMode:(CPToolbarDisplayMode)aDisplayMode
214 - (void)setVisible:(BOOL)aFlag
216 if (_isVisible === aFlag)
221 [_window _noteToolbarChanged];
224 - (void)setSizeMode:(CPToolbarSizeMode)aSize
226 if (aSize === _sizeMode)
230 [[
self _toolbarView] setFrame:[
self _toolbarViewFrame]];
231 [_window _noteToolbarChanged];
239 - (void)_setWindow:(
CPWindow)aWindow
254 - (void)setDelegate:(
id)aDelegate
256 if (_delegate === aDelegate)
259 _delegate = aDelegate;
261 [
self _reloadToolbarItems];
264 - (void)setDisplayMode:(CPToolbarDisplayMode)aDisplayMode
266 if (_displayMode === aDisplayMode)
268 _displayMode = aDisplayMode;
270 [
self _reloadToolbarItems];
274 - (void)_loadConfiguration
279 - (CGRect)_toolbarViewFrame
281 var height = _desiredHeight || (_sizeMode !=
CPToolbarSizeModeSmall ? [
self _valueForThemeAttribute:@"regular-size-height"] : [
self _valueForThemeAttribute:@"small-size-height"]);
290 - (id)_valueForThemeAttribute:(
CPString)attributeName
292 return [[[
self class] _themeAttributes] valueForKey:attributeName];
300 _toolbarView = [[_CPToolbarView alloc] initWithFrame:[
self _toolbarViewFrame]];
302 [_toolbarView setToolbar:self];
303 [_toolbarView setAutoresizingMask:CPViewWidthSizable];
304 [_toolbarView reloadToolbarItems];
311 - (void)_reloadToolbarItems
318 _itemIdentifiers = [_defaultItems valueForKey:@"itemIdentifier"] || [];
320 if ([_delegate respondsToSelector:
@selector(toolbarDefaultItemIdentifiers:)])
322 var itemIdentifiersFromDelegate = [_delegate toolbarDefaultItemIdentifiers:self];
326 if (itemIdentifiersFromDelegate)
327 _itemIdentifiers = [itemIdentifiersFromDelegate arrayByAddingObjectsFromArray:_itemIdentifiers];
333 count = [_itemIdentifiers count];
337 for (; index < count; ++index)
339 var identifier = _itemIdentifiers[index],
340 item = [
CPToolbarItem _standardItemWithItemIdentifier:identifier];
344 item = [_identifiedItems objectForKey:identifier];
346 if (!item && _delegate)
347 item = [_delegate toolbar:
self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES];
353 reason:
@"Toolbar delegate " + _delegate +
" returned nil toolbar item for identifier \"" + identifier +
"\""];
355 item._toolbar =
self;
357 [_items addObject:item];
365 _itemsSortedByVisibilityPriority = [_items sortedArrayUsingFunction:_CPToolbarItemVisibilityPriorityCompare context:NULL];
367 [_toolbarView reloadToolbarItems];
383 return [_toolbarView visibleItems];
391 return _itemsSortedByVisibilityPriority;
398 - (void)validateVisibleItems
400 [
self _validateVisibleItems:NO]
403 - (void)_autoValidateVisibleItems
405 [
self _validateVisibleItems:YES]
408 - (void)_validateVisibleItems:(BOOL)isAutovalidation
410 var toolbarItems = [
self visibleItems],
411 count = [toolbarItems count];
415 var item = [toolbarItems objectAtIndex:count];
416 if (!isAutovalidation || [item autovalidates])
422 - (id)_itemForItemIdentifier:(
CPString)identifier willBeInsertedIntoToolbar:(BOOL)toolbar
424 var item = [_identifiedItems objectForKey:identifier];
427 item = [
CPToolbarItem _standardItemWithItemIdentifier:identifier];
428 if (_delegate && !item)
430 item = [[_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:toolbar] copy];
433 reason:
@"Toolbar delegate " + _delegate +
" returned nil toolbar item for identifier " + identifier];
436 [_identifiedItems setObject:item forKey:identifier];
443 - (id)_itemsWithIdentifiers:(
CPArray)identifiers
446 for (var i = 0; i < identifiers.length; i++)
447 [items addObject:[self _itemForItemIdentifier:identifiers[i] willBeInsertedIntoToolbar:NO]];
453 - (id)_defaultToolbarItems
455 if (!_defaultItems && [_delegate respondsToSelector:
@selector(toolbarDefaultItemIdentifiers:)])
459 var identifiers = [_delegate toolbarDefaultItemIdentifiers:self],
461 count = [identifiers count];
463 for (; index < count; ++index)
464 [_defaultItems addObject:[self _itemForItemIdentifier:identifiers[index] willBeInsertedIntoToolbar:NO]];
467 return _defaultItems;
476 if ([_identifiedItems objectForKey:[anItem itemIdentifier]])
477 [_identifiedItems setObject:anItem forKey:[anItem itemIdentifier]];
480 count = [_items count];
482 for (; index <= count; ++index)
484 var item = _items[index];
486 if ([item itemIdentifier] === [anItem itemIdentifier])
488 _items[index] = anItem;
489 _itemsSortedByVisibilityPriority = [_items sortedArrayUsingFunction:_CPToolbarItemVisibilityPriorityCompare context:NULL];
491 [_toolbarView reloadToolbarItems];
523 _identifier = [aCoder decodeObjectForKey:CPToolbarIdentifierKey];
524 _displayMode = [aCoder decodeIntForKey:CPToolbarDisplayModeKey];
525 _showsBaselineSeparator = [aCoder decodeBoolForKey:CPToolbarShowsBaselineSeparatorKey];
526 _allowsUserCustomization = [aCoder decodeBoolForKey:CPToolbarAllowsUserCustomizationKey];
527 _isVisible = [aCoder decodeBoolForKey:CPToolbarIsVisibleKey];
528 _sizeMode = [aCoder decodeIntForKey:CPToolbarSizeModeKey];
530 _identifiedItems = [aCoder decodeObjectForKey:CPToolbarIdentifiedItemsKey];
531 _defaultItems = [aCoder decodeObjectForKey:CPToolbarDefaultItemsKey];
532 _allowedItems = [aCoder decodeObjectForKey:CPToolbarAllowedItemsKey];
533 _selectableItems = [aCoder decodeObjectForKey:CPToolbarSelectableItemsKey];
535 [[_identifiedItems allValues] makeObjectsPerformSelector:@selector(_setToolbar:) withObject:self];
539 [
CPToolbar _addToolbar:self forIdentifier:_identifier];
542 [
self setDelegate:[aCoder decodeObjectForKey:CPToolbarDelegateKey]];
570 [aCoder encodeObject:_identifier forKey:CPToolbarIdentifierKey];
571 [aCoder encodeInt:_displayMode forKey:CPToolbarDisplayModeKey];
572 [aCoder encodeBool:_showsBaselineSeparator forKey:CPToolbarShowsBaselineSeparatorKey];
573 [aCoder encodeBool:_allowsUserCustomization forKey:CPToolbarAllowsUserCustomizationKey];
574 [aCoder encodeBool:_isVisible forKey:CPToolbarIsVisibleKey];
575 [aCoder encodeInt:_sizeMode forKey:CPToolbarSizeModeKey]
577 [aCoder encodeObject:_identifiedItems forKey:CPToolbarIdentifiedItemsKey];
578 [aCoder encodeObject:_defaultItems forKey:CPToolbarDefaultItemsKey];
579 [aCoder encodeObject:_allowedItems forKey:CPToolbarAllowedItemsKey];
580 [aCoder encodeObject:_selectableItems forKey:CPToolbarSelectableItemsKey];
582 [aCoder encodeConditionalObject:_delegate forKey:CPToolbarDelegateKey];
588 var _CPToolbarViewBackgroundColor = nil,
589 _CPToolbarViewExtraItemsImage = nil,
590 _CPToolbarViewExtraItemsAlternateImage = nil;
595 var _CPToolbarItemInfoMake =
function(anIndex, aView, aLabel, aMinWidth)
597 return { index:anIndex, view:aView,
label:aLabel, minWidth:aMinWidth };
601 @implementation _CPToolbarView :
CPView
609 JSObject _viewsForToolbarItems;
625 if (
self !== [_CPToolbarView
class])
632 _CPToolbarViewExtraItemsAlternateImage = [[
CPImage alloc]
initWithContentsOfFile:[bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsAlternateImage.png"]
size:_CGSizeMake(10.0, 15.0)];
635 - (id)initWithFrame:(CGRect)aFrame
637 self = [
super initWithFrame:aFrame];
647 [_additionalItemsButton setBordered:NO];
649 [_additionalItemsButton setImagePosition:CPImageOnly];
650 [[_additionalItemsButton menu] setShowsStateColumn:NO];
651 [[_additionalItemsButton menu] setAutoenablesItems:NO];
653 [_additionalItemsButton setAlternateImage:_CPToolbarViewExtraItemsAlternateImage];
669 - (void)FIXME_setIsHUD:(BOOL)shouldBeHUD
671 if (_FIXME_isHUD === shouldBeHUD)
674 _FIXME_isHUD = shouldBeHUD;
676 var items = [_toolbar items],
677 count = [items count];
680 [[
self viewForItem:items[count]] FIXME_setIsHUD:shouldBeHUD];
684 - (void)resizeSubviewsWithOldSize:(CGSize)aSize
691 return _viewsForToolbarItems[[anItem
UID]] || nil;
697 var items = [_toolbar items],
698 itemsWidth = _CGRectGetWidth([
self bounds]),
699 minWidth = _minWidth,
701 invisibleItemsSortedByPriority = [];
703 _visibleItems = items;
707 if (itemsWidth < minWidth)
711 _visibleItems = [_visibleItems copy];
713 var itemsSortedByVisibilityPriority = [_toolbar itemsSortedByVisibilityPriority],
714 count = itemsSortedByVisibilityPriority.length;
720 while (minWidth > itemsWidth && count)
722 var item = itemsSortedByVisibilityPriority[--count],
723 view = [
self viewForItem:item];
727 [_visibleItems removeObjectIdenticalTo:item];
728 [invisibleItemsSortedByPriority addObject:item];
730 [view setHidden:YES];
731 [view FIXME_setIsHUD:_FIXME_isHUD];
736 var count = [items count],
741 var view = [
self viewForItem:items[count]],
742 minSize = [view minSize];
744 if (height < minSize.height)
745 height = minSize.height;
751 var contentInset = [_toolbar _valueForThemeAttribute:@"content-inset"],
752 newDesiredHeight = height ? height + contentInset.top + contentInset.bottom : 0;
754 if (newDesiredHeight != _toolbar._desiredHeight)
758 _toolbar._desiredHeight = newDesiredHeight;
760 [
self setFrame:[_toolbar _toolbarViewFrame]];
761 [_toolbar._window _noteToolbarChanged];
768 var count = _visibleItems.length,
773 var item = _visibleItems[count],
774 view = [
self viewForItem:item],
775 minSize = [view minSize];
777 if (minSize.width !== [view maxSize].width)
778 [flexibleItemIndexes addIndex:count];
785 [view setFrameSize:_CGSizeMake(minSize.width, height)];
790 var remainingSpace = itemsWidth - minWidth,
796 while (remainingSpace && [flexibleItemIndexes count])
799 proportionate += remainingSpace / [flexibleItemIndexes count];
802 remainingSpace = 0.0;
806 while ((index = [flexibleItemIndexes indexGreaterThanIndex:index]) !==
CPNotFound)
808 var item = _visibleItems[index],
809 view = [
self viewForItem:item],
810 proposedWidth = [view minSize].width + proportionate,
811 constrainedWidth = MIN(proposedWidth, [view maxSize].
width);
813 if (constrainedWidth < proposedWidth)
815 [flexibleItemIndexes removeIndex:index];
817 remainingSpace += proposedWidth - constrainedWidth;
820 [view setFrameSize:_CGSizeMake(constrainedWidth, height)];
826 count = _visibleItems.length,
827 x = contentInset.left,
828 contentInset = [_toolbar _valueForThemeAttribute:@"content-inset"],
829 y = contentInset.top;
831 for (; index < count; ++index)
833 var view = [
self viewForItem:_visibleItems[index]],
834 viewWidth = _CGRectGetWidth([view
frame]);
836 [view setFrame:_CGRectMake(x, y, viewWidth, height)];
841 var needsAdditionalItemsButton = NO;
843 if ([invisibleItemsSortedByPriority count])
846 count = [items count];
848 _invisibleItems = [];
850 for (; index < count; ++index)
852 var item = items[index];
854 if ([invisibleItemsSortedByPriority indexOfObjectIdenticalTo:item] !==
CPNotFound)
856 [_invisibleItems addObject:item];
858 var identifier = [item itemIdentifier];
863 needsAdditionalItemsButton = YES;
868 if (needsAdditionalItemsButton)
870 [_additionalItemsButton setFrameOrigin:_CGPointMake(itemsWidth + 5.0, (_CGRectGetHeight([
self bounds]) - _CGRectGetHeight([_additionalItemsButton frame])) / 2.0)];
872 [
self addSubview:_additionalItemsButton];
874 [_additionalItemsButton removeAllItems];
876 [_additionalItemsButton addItemWithTitle:@"Additional Items"];
877 [[_additionalItemsButton itemArray][0] setImage:_CPToolbarViewExtraItemsImage];
880 count = [_invisibleItems count],
881 hasNonSeparatorItem = NO;
883 for (; index < count; ++index)
885 var item = _invisibleItems[index],
886 identifier = [item itemIdentifier];
894 if (hasNonSeparatorItem)
895 [_additionalItemsButton addItem:[
CPMenuItem separatorItem]];
900 hasNonSeparatorItem = YES;
904 [menuItem setRepresentedObject:item];
905 [menuItem setImage:[item image]];
906 [menuItem setTarget:self];
907 [menuItem setEnabled:[item isEnabled]];
909 [_additionalItemsButton addItem:menuItem];
913 [_additionalItemsButton removeFromSuperview];
921 - (void)didSelectMenuItem:(
id)aSender
923 var toolbarItem = [aSender representedObject];
925 [CPApp sendAction:[toolbarItem action] to:[toolbarItem target] from:toolbarItem];
928 - (void)reloadToolbarItems
931 var subviews = [
self subviews],
935 [subviews[count] removeFromSuperview];
938 var items = [_toolbar items],
941 count = items.length;
944 _viewsForToolbarItems = { };
946 for (; index < count; ++index)
948 var item = items[index],
949 view = [[_CPToolbarItemView alloc] initWithToolbarItem:item toolbar:self];
951 _viewsForToolbarItems[[item UID]] = view;
953 if ([item toolTip] && [view respondsToSelector:
@selector(setToolTip:)])
954 [view setToolTip:[item toolTip]];
956 [
self addSubview:view];
967 var _CPToolbarItemVisibilityPriorityCompare =
function(lhs, rhs)
969 var lhsVisibilityPriority = [lhs visibilityPriority],
970 rhsVisibilityPriority = [rhs visibilityPriority];
972 if (lhsVisibilityPriority == rhsVisibilityPriority)
975 if (lhsVisibilityPriority > rhsVisibilityPriority)
983 @implementation _CPToolbarItemView :
CPControl
1002 self = [
super init];
1006 _toolbarItem = aToolbarItem;
1011 [_labelField setTextColor:[
self FIXME_labelColor]];
1012 [_labelField setTextShadowColor:[
self FIXME_labelShadowColor]];
1013 [_labelField setTextShadowOffset:_CGSizeMake(0.0, 1.0)];
1014 [_labelField setAutoresizingMask:CPViewWidthSizable | CPViewMinXMargin];
1016 [
self addSubview:_labelField];
1018 [
self updateFromItem];
1020 _toolbar = aToolbar;
1022 var keyPaths = [@"label", @"image", @"alternateImage", @"minSize", @"maxSize", @"target", @"action", @"enabled"],
1024 count = [keyPaths count];
1026 for (; index < count; ++index)
1029 forKeyPath:keyPaths[index]
1037 - (void)FIXME_setIsHUD:(BOOL)shouldBeHUD
1039 _FIXME_isHUD = shouldBeHUD;
1040 [_labelField setTextColor:[
self FIXME_labelColor]];
1041 [_labelField setTextShadowColor:[
self FIXME_labelShadowColor]];
1044 - (void)updateFromItem
1046 var identifier = [_toolbarItem itemIdentifier];
1052 [_view removeFromSuperview];
1053 [_imageView removeFromSuperview];
1055 _minSize = [_toolbarItem minSize];
1056 _maxSize = [_toolbarItem maxSize];
1060 _view = [[
CPView alloc] initWithFrame:_CGRectMake(0.0, 0.0, 2.0, 32.0)];
1064 sizes[@"CPToolbarItemSeparator"] = [_CGSizeMake(2.0, 26.0), _CGSizeMake(2.0, 1.0), _CGSizeMake(2.0, 26.0)];
1065 [_view setBackgroundColor:_CPControlThreePartImagePattern(YES, sizes, @"CPToolbarItem", @"Separator")];
1067 [
self addSubview:_view];
1073 [
self setTarget:[_toolbarItem target]];
1074 [
self setAction:[_toolbarItem action]];
1076 var view = [_toolbarItem view] || nil;
1081 [_view removeFromSuperview];
1085 [
self addSubview:view];
1086 [_imageView removeFromSuperview];
1098 [_imageView setImageScaling:CPImageScaleProportionallyDown];
1100 [
self addSubview:_imageView];
1103 [_imageView setImage:[_toolbarItem image]];
1106 var minSize = [_toolbarItem minSize],
1107 maxSize = [_toolbarItem maxSize];
1109 [_labelField setStringValue:[_toolbarItem label]];
1110 [_labelField sizeToFit];
1112 [
self setEnabled:[_toolbarItem isEnabled]];
1114 _labelSize = [_labelField frame].size;
1118 [_labelField setHidden:iconOnly];
1119 [_view setHidden:labelOnly];
1121 _minSize = _CGSizeMake(MAX(_labelSize.width, minSize.width), (labelOnly ? 0 : minSize.height) + (iconOnly ? 0 : _labelSize.height + LABEL_MARGIN));
1122 _maxSize = _CGSizeMake(MAX(_labelSize.width, maxSize.width), 100000000.0);
1127 - (void)layoutSubviews
1129 var identifier = [_toolbarItem itemIdentifier];
1135 var bounds = [
self bounds],
1136 width = _CGRectGetWidth(bounds);
1139 return [_view setFrame:_CGRectMake(ROUND((width - 2.0) / 2.0), 0.0, 2.0, _CGRectGetHeight(bounds))];
1142 var view = _view || _imageView,
1143 itemMaxSize = [_toolbarItem maxSize],
1145 height = _CGRectGetHeight(bounds) - (iconOnly ? 0 : _labelSize.height),
1147 viewHeight = MIN(itemMaxSize.height, height);
1149 [view setFrame:_CGRectMake(ROUND((width - viewWidth) / 2.0),
1150 ROUND((height - viewHeight) / 2.0),
1155 [_labelField setFrameOrigin:_CGPointMake(ROUND((width - _labelSize.width) / 2.0), _CGRectGetHeight(bounds) - _labelSize.height)];
1158 - (void)mouseDown:(
CPEvent)anEvent
1160 if ([_toolbarItem view])
1161 return [[
self nextResponder] mouseDown:anEvent];
1163 var identifier = [_toolbarItem itemIdentifier];
1168 return [[
self nextResponder] mouseDown:anEvent];
1170 [
super mouseDown:anEvent];
1173 - (void)setEnabled:(BOOL)shouldBeEnabled
1176 if ([
self isEnabled] === shouldBeEnabled)
1179 [
super setEnabled:shouldBeEnabled];
1181 if (shouldBeEnabled)
1183 [_imageView setAlphaValue:1.0];
1184 [_labelField setAlphaValue:1.0];
1188 [_imageView setAlphaValue:0.5];
1189 [_labelField setAlphaValue:0.5];
1203 - (
CPColor)FIXME_labelShadowColor
1211 - (void)setHighlighted:(BOOL)shouldBeHighlighted
1213 [
super setHighlighted:shouldBeHighlighted];
1215 if (shouldBeHighlighted)
1217 var alternateImage = [_toolbarItem alternateImage];
1220 [_imageView setImage:alternateImage];
1222 [_labelField setTextShadowOffset:_CGSizeMakeZero()];
1226 var image = [_toolbarItem image];
1229 [_imageView setImage:image];
1231 [_labelField setTextShadowOffset:_CGSizeMake(0.0, 1.0)];
1234 [_labelField setTextShadowColor:[
self FIXME_labelShadowColor]];
1237 - (void)sendAction:(
SEL)anAction to:(
id)aSender
1239 [CPApp sendAction:anAction to:aSender from:_toolbarItem];
1242 - (void)observeValueForKeyPath:(
CPString)aKeyPath
1243 ofObject:(
id)anObject
1245 context:(
id)aContext
1247 if (aKeyPath ===
"enabled")
1248 [
self setEnabled:[anObject isEnabled]];
1250 else if (aKeyPath ===
@"target")
1251 [
self setTarget:[anObject target]];
1253 else if (aKeyPath ===
@"action")
1254 [
self setAction:[anObject action]];
1257 [
self updateFromItem];
1267 - (CPToolbarDisplayMode)displayMode
1269 return _displayMode;
1275 - (void)setDisplayMode:(CPToolbarDisplayMode)aValue
1277 _displayMode = aValue;
1291 - (void)setSizeMode:(
int)aValue