00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 @import <Foundation/CPObject.j>
00027
00028 @import "CPPopUpButton.j"
00029 @import "CPToolbarItem.j"
00030
00031 #include "CoreGraphics/CGGeometry.h"
00032
00033
00034
00035
00036
00037
00038 CPToolbarDisplayModeDefault = 0;
00039
00040
00041
00042
00043 CPToolbarDisplayModeIconAndLabel = 1;
00044
00045
00046
00047
00048 CPToolbarDisplayModeIconOnly = 2;
00049
00050
00051
00052
00053 CPToolbarDisplayModeLabelOnly = 3;
00054
00055 var CPToolbarsByIdentifier = nil;
00056 var CPToolbarConfigurationsByIdentifier = nil;
00057
00085 @implementation CPToolbar : CPObject
00086 {
00087 CPString _identifier;
00088 CPToolbarDisplayMode _displayMode;
00089 BOOL _showsBaselineSeparator;
00090 BOOL _allowsUserCustomization;
00091 BOOL _isVisible;
00092
00093 id _delegate;
00094
00095 CPArray _itemIdentifiers;
00096
00097 CPDictionary _identifiedItems;
00098 CPArray _defaultItems;
00099 CPArray _allowedItems;
00100 CPArray _selectableItems;
00101
00102 CPArray _items;
00103 CPArray _itemsSortedByVisibilityPriority;
00104
00105 CPView _toolbarView;
00106 CPWindow _window;
00107 }
00108
00109
00110 + (void)initialize
00111 {
00112 if (self != [CPToolbar class])
00113 return;
00114
00115 CPToolbarsByIdentifier = [CPDictionary dictionary];
00116 CPToolbarConfigurationsByIdentifier = [CPDictionary dictionary];
00117 }
00118
00119
00120 + (void)_addToolbar:(CPToolbar)toolbar forIdentifier:(CPString)identifier
00121 {
00122 var toolbarsSharingIdentifier = [CPToolbarsByIdentifier objectForKey:identifier];
00123
00124 if (!toolbarsSharingIdentifier)
00125 {
00126 toolbarsSharingIdentifier = []
00127 [CPToolbarsByIdentifier setObject:toolbarsSharingIdentifier forKey:identifier];
00128 }
00129
00130 [toolbarsSharingIdentifier addObject:toolbar];
00131 }
00132
00133 - (id)init
00134 {
00135 return [self initWithIdentifier:@""];
00136 }
00137
00143 - (id)initWithIdentifier:(CPString)anIdentifier
00144 {
00145 self = [super init];
00146
00147 if (self)
00148 {
00149 _items = [];
00150
00151 _identifier = anIdentifier;
00152 _isVisible = YES;
00153
00154 [CPToolbar _addToolbar:self forIdentifier:_identifier];
00155 }
00156
00157 return self;
00158 }
00159
00160
00164 - (void)setDisplayMode:(CPToolbarDisplayMode)aDisplayMode
00165 {
00166
00167 }
00168
00172 - (CPString)identifier
00173 {
00174 return _identifier;
00175 }
00176
00180 - (id)delegate
00181 {
00182 return _delegate;
00183 }
00184
00188 - (BOOL)isVisible
00189 {
00190 return _isVisible;
00191 }
00192
00197 - (void)setVisible:(BOOL)aFlag
00198 {
00199 if (_isVisible === aFlag)
00200 return;
00201
00202 _isVisible = aFlag;
00203
00204 [_window _noteToolbarChanged];
00205 }
00206
00207 - (CPWindow)_window
00208 {
00209 return _window;
00210 }
00211
00212 - (void)_setWindow:(CPWindow)aWindow
00213 {
00214 _window = aWindow;
00215 }
00216
00221 - (void)setDelegate:(id)aDelegate
00222 {
00223 if (_delegate === aDelegate)
00224 return;
00225
00226 _delegate = aDelegate;
00227
00228 [self _reloadToolbarItems];
00229 }
00230
00231
00232 - (void)_loadConfiguration
00233 {
00234
00235 }
00236
00237
00238 - (CPView)_toolbarView
00239 {
00240 if (!_toolbarView)
00241 {
00242 _toolbarView = [[_CPToolbarView alloc] initWithFrame:CPRectMake(0.0, 0.0, 1200.0, 59.0)];
00243
00244 [_toolbarView setToolbar:self];
00245 [_toolbarView setAutoresizingMask:CPViewWidthSizable];
00246 [_toolbarView reloadToolbarItems];
00247 }
00248
00249 return _toolbarView;
00250 }
00251
00252
00253 - (void)_reloadToolbarItems
00254 {
00255
00256
00257
00258
00259
00260 _itemIdentifiers = [_defaultItems valueForKey:@"itemIdentifier"] || [];
00261
00262 if (_delegate)
00263 {
00264 var itemIdentifiersFromDelegate = [[_delegate toolbarDefaultItemIdentifiers:self] mutableCopy];
00265
00266 if (itemIdentifiersFromDelegate)
00267 _itemIdentifiers = [_itemIdentifiers arrayByAddingObjectsFromArray:itemIdentifiersFromDelegate];
00268 }
00269
00270 var index = 0,
00271 count = [_itemIdentifiers count];
00272
00273 _items = [];
00274
00275 for (; index < count; ++index)
00276 {
00277 var identifier = _itemIdentifiers[index],
00278 item = [CPToolbarItem _standardItemWithItemIdentifier:identifier];
00279
00280
00281 if (!item)
00282 item = [_identifiedItems objectForKey:identifier];
00283
00284 if (!item && _delegate)
00285 item = [_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES];
00286
00287 item = [item copy];
00288
00289 if (item === nil)
00290 [CPException raise:CPInvalidArgumentException
00291 reason:@"Toolbar delegate " + _delegate + " returned nil toolbar item for identifier \"" + identifier + "\""];
00292
00293 item._toolbar = self;
00294
00295 [_items addObject:item];
00296 }
00297
00298
00299
00300
00301
00302
00303 _itemsSortedByVisibilityPriority = [_items sortedArrayUsingFunction:_CPToolbarItemVisibilityPriorityCompare context:NULL];
00304
00305 [_toolbarView reloadToolbarItems];
00306 }
00307
00311 - (CPArray)items
00312 {
00313 return _items;
00314 }
00315
00319 - (CPArray)visibleItems
00320 {
00321 return [_toolbarView visibleItems];
00322 }
00323
00327 - (CPArray)itemsSortedByVisibilityPriority
00328 {
00329 return _itemsSortedByVisibilityPriority;
00330 }
00331
00332 - (void)validateVisibleToolbarItems
00333 {
00334 var toolbarItems = [self visibleItems],
00335 count = [toolbarItems count];
00336
00337 while (count--)
00338 [toolbarItems[count] validate];
00339 }
00340
00341
00342 - (id)_itemForItemIdentifier:(CPString)identifier willBeInsertedIntoToolbar:(BOOL)toolbar
00343 {
00344 var item = [_identifiedItems objectForKey:identifier];
00345 if (!item)
00346 {
00347 item = [CPToolbarItem _standardItemWithItemIdentifier:identifier];
00348 if (_delegate && !item)
00349 {
00350 item = [[_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:toolbar] copy];
00351 if (!item)
00352 [CPException raise:CPInvalidArgumentException
00353 reason:@"Toolbar delegate " + _delegate + " returned nil toolbar item for identifier " + identifier];
00354 }
00355
00356 [_identifiedItems setObject:item forKey:identifier];
00357 }
00358
00359 return item;
00360 }
00361
00362
00363 - (id)_itemsWithIdentifiers:(CPArray)identifiers
00364 {
00365 var items = [];
00366 for (var i = 0; i < identifiers.length; i++)
00367 [items addObject:[self _itemForItemIdentifier:identifiers[i] willBeInsertedIntoToolbar:NO]];
00368
00369 return items;
00370 }
00371
00372
00373 - (id)_defaultToolbarItems
00374 {
00375 if (!_defaultItems && [_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)])
00376 {
00377 _defaultItems = [];
00378
00379 var identifiers = [_delegate toolbarDefaultItemIdentifiers:self],
00380 index = 0,
00381 count = [identifiers count];
00382
00383 for (; index < count; ++index)
00384 [_defaultItems addObject:[self _itemForItemIdentifier:identifiers[index] willBeInsertedIntoToolbar:NO]];
00385 }
00386
00387 return _defaultItems;
00388 }
00389
00394 - (void)toolbarItemDidChange:(CPToolbarItem)anItem
00395 {
00396 if ([_identifiedItems objectForKey:[anItem itemIdentifier]])
00397 [_identifiedItems setObject:anItem forKey:[anItem itemIdentifier]];
00398
00399 var index = 0,
00400 count = [_items count];
00401
00402 for (; index <= count; ++index)
00403 {
00404 var item = _items[index];
00405
00406 if ([item itemIdentifier] === [anItem itemIdentifier])
00407 {
00408 _items[index] = anItem;
00409 _itemsSortedByVisibilityPriority = [_items sortedArrayUsingFunction:_CPToolbarItemVisibilityPriorityCompare context:NULL];
00410
00411 [_toolbarView reloadToolbarItems];
00412 }
00413 }
00414 }
00415
00416 @end
00417
00418
00419 var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
00420 CPToolbarDisplayModeKey = @"CPToolbarDisplayModeKey",
00421 CPToolbarShowsBaselineSeparatorKey = @"CPToolbarShowsBaselineSeparatorKey",
00422 CPToolbarAllowsUserCustomizationKey = @"CPToolbarAllowsUserCustomizationKey",
00423 CPToolbarIsVisibleKey = @"CPToolbarIsVisibleKey",
00424 CPToolbarDelegateKey = @"CPToolbarDelegateKey",
00425 CPToolbarIdentifiedItemsKey = @"CPToolbarIdentifiedItemsKey",
00426 CPToolbarDefaultItemsKey = @"CPToolbarDefaultItemsKey",
00427 CPToolbarAllowedItemsKey = @"CPToolbarAllowedItemsKey",
00428 CPToolbarSelectableItemsKey = @"CPToolbarSelectableItemsKey";
00429
00430 @implementation CPToolbar (CPCoding)
00431
00432
00433
00434
00435
00436 - (id)initWithCoder:(CPCoder)aCoder
00437 {
00438 self = [super init];
00439
00440 if (self)
00441 {
00442 _identifier = [aCoder decodeObjectForKey:CPToolbarIdentifierKey];
00443 _displayMode = [aCoder decodeIntForKey:CPToolbarDisplayModeKey];
00444 _showsBaselineSeparator = [aCoder decodeBoolForKey:CPToolbarShowsBaselineSeparatorKey];
00445 _allowsUserCustomization = [aCoder decodeBoolForKey:CPToolbarAllowsUserCustomizationKey];
00446 _isVisible = [aCoder decodeBoolForKey:CPToolbarIsVisibleKey];
00447
00448 _identifiedItems = [aCoder decodeObjectForKey:CPToolbarIdentifiedItemsKey];
00449 _defaultItems = [aCoder decodeObjectForKey:CPToolbarDefaultItemsKey];
00450 _allowedItems = [aCoder decodeObjectForKey:CPToolbarAllowedItemsKey];
00451 _selectableItems = [aCoder decodeObjectForKey:CPToolbarSelectableItemsKey];
00452
00453 [[_identifiedItems allValues] makeObjectsPerformSelector:@selector(_setToolbar:) withObject:self];
00454
00455 _items = [];
00456
00457 [CPToolbar _addToolbar:self forIdentifier:_identifier];
00458
00459
00460 [self setDelegate:[aCoder decodeObjectForKey:CPToolbarDelegateKey]];
00461
00462
00463
00464
00465
00466
00467
00468
00469 [self _reloadToolbarItems];
00470 }
00471
00472 return self;
00473 }
00474
00475
00476
00477
00478
00479 - (void)encodeWithCoder:(CPCoder)aCoder
00480 {
00481 [aCoder encodeObject:_identifier forKey:CPToolbarIdentifierKey];
00482 [aCoder encodeInt:_displayMode forKey:CPToolbarDisplayModeKey];
00483 [aCoder encodeBool:_showsBaselineSeparator forKey:CPToolbarShowsBaselineSeparatorKey];
00484 [aCoder encodeBool:_allowsUserCustomization forKey:CPToolbarAllowsUserCustomizationKey];
00485 [aCoder encodeBool:_isVisible forKey:CPToolbarIsVisibleKey];
00486
00487 [aCoder encodeObject:_identifiedItems forKey:CPToolbarIdentifiedItemsKey];
00488 [aCoder encodeObject:_defaultItems forKey:CPToolbarDefaultItemsKey];
00489 [aCoder encodeObject:_allowedItems forKey:CPToolbarAllowedItemsKey];
00490 [aCoder encodeObject:_selectableItems forKey:CPToolbarSelectableItemsKey];
00491
00492 [aCoder encodeConditionalObject:_delegate forKey:CPToolbarDelegateKey];
00493 }
00494
00495 @end
00496
00497
00498 var _CPToolbarViewBackgroundColor = nil,
00499 _CPToolbarViewExtraItemsImage = nil,
00500 _CPToolbarViewExtraItemsAlternateImage = nil;
00501
00502 var TOOLBAR_TOP_MARGIN = 5.0,
00503 TOOLBAR_ITEM_MARGIN = 10.0,
00504 TOOLBAR_EXTRA_ITEMS_WIDTH = 20.0;
00505
00506 var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
00507 {
00508 return { index:anIndex, view:aView, label:aLabel, minWidth:aMinWidth };
00509 }
00510
00511
00512 @implementation _CPToolbarView : CPView
00513 {
00514 CPToolbar _toolbar;
00515
00516 CPIndexSet _flexibleWidthIndexes;
00517 CPIndexSet _visibleFlexibleWidthIndexes;
00518
00519 CPDictionary _itemInfos;
00520 JSObject _viewsForToolbarItems;
00521
00522 CPArray _visibleItems @accessors(readonly, property=visibleItems);
00523 CPArray _invisibleItems;
00524
00525 CPPopUpButton _additionalItemsButton;
00526 CPColor _labelColor;
00527 CPColor _labelShadowColor;
00528
00529 float _minWidth;
00530
00531 BOOL _FIXME_isHUD;
00532 }
00533
00534 + (void)initialize
00535 {
00536 if (self !== [_CPToolbarView class])
00537 return;
00538
00539 var bundle = [CPBundle bundleForClass:self];
00540
00541 _CPToolbarViewExtraItemsImage = [[CPImage alloc] initWithContentsOfFile: [bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsImage.png"] size: CPSizeMake(10.0, 15.0)];
00542
00543 _CPToolbarViewExtraItemsAlternateImage = [[CPImage alloc] initWithContentsOfFile: [bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsAlternateImage.png"] size:CGSizeMake(10.0, 15.0)];
00544 }
00545
00546 - (id)initWithFrame:(CGRect)aFrame
00547 {
00548 self = [super initWithFrame:aFrame];
00549
00550 if (self)
00551 {
00552 _minWidth = 0;
00553
00554 _labelColor = [CPColor blackColor];
00555 _labelShadowColor = [CPColor colorWithWhite:1.0 alpha:0.75];
00556
00557 _additionalItemsButton = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 15.0) pullsDown:YES];
00558 [_additionalItemsButton setBordered:NO];
00559
00560 [_additionalItemsButton setImagePosition:CPImageOnly];
00561 [[_additionalItemsButton menu] setShowsStateColumn:NO];
00562
00563 [_additionalItemsButton setAlternateImage:_CPToolbarViewExtraItemsAlternateImage];
00564 }
00565
00566 return self;
00567 }
00568
00569 - (void)setToolbar:(CPToolbar)aToolbar
00570 {
00571 _toolbar = aToolbar;
00572 }
00573
00574 - (CPToolbar)toolbar
00575 {
00576 return _toolbar;
00577 }
00578
00579 - (void)FIXME_setIsHUD:(BOOL)shouldBeHUD
00580 {
00581 if (_FIXME_isHUD === shouldBeHUD)
00582 return;
00583
00584 _FIXME_isHUD = shouldBeHUD;
00585
00586 var items = [_toolbar items],
00587 count = [items count];
00588
00589 while (count--)
00590 [[self viewForItem:items[count]] FIXME_setIsHUD:shouldBeHUD];
00591 }
00592
00593
00594 - (void)resizeSubviewsWithOldSize:(CGSize)aSize
00595 {
00596 [self tile];
00597 }
00598
00599 - (_CPToolbarItemView)viewForItem:(CPToolbarItem)anItem
00600 {
00601 return _viewsForToolbarItems[[anItem UID]] || nil;
00602 }
00603
00604 - (void)tile
00605 {
00606
00607 var items = [_toolbar items],
00608 itemsWidth = CGRectGetWidth([self bounds]),
00609 minWidth = _minWidth,
00610
00611 invisibleItemsSortedByPriority = [];
00612
00613 _visibleItems = items;
00614
00615
00616
00617 if (itemsWidth < minWidth)
00618 {
00619 itemsWidth -= TOOLBAR_EXTRA_ITEMS_WIDTH;
00620
00621 _visibleItems = [_visibleItems copy];
00622
00623 var itemsSortedByVisibilityPriority = [_toolbar itemsSortedByVisibilityPriority],
00624 count = itemsSortedByVisibilityPriority.length;
00625
00626
00627
00628
00629
00630 while (minWidth > itemsWidth && count)
00631 {
00632 var item = itemsSortedByVisibilityPriority[--count],
00633 view = [self viewForItem:item];
00634
00635 minWidth -= [view minSize].width + TOOLBAR_ITEM_MARGIN;
00636
00637 [_visibleItems removeObjectIdenticalTo:item];
00638 [invisibleItemsSortedByPriority addObject:item];
00639
00640 [view setHidden:YES];
00641 [view FIXME_setIsHUD:_FIXME_isHUD];
00642 }
00643 }
00644
00645
00646 var count = [items count],
00647 height = 0.0;
00648
00649 while (count--)
00650 {
00651 var view = [self viewForItem:items[count]],
00652 minSize = [view minSize];
00653
00654 if (height < minSize.height)
00655 height = minSize.height;
00656 }
00657
00658
00659
00660 var count = _visibleItems.length
00661 flexibleItemIndexes = [CPIndexSet indexSet];
00662
00663 while (count--)
00664 {
00665 var item = _visibleItems[count],
00666 view = [self viewForItem:item],
00667 minSize = [view minSize];
00668
00669 if (minSize.width !== [view maxSize].width)
00670 [flexibleItemIndexes addIndex:count];
00671
00672
00673
00674
00675
00676 else
00677 [view setFrameSize:CGSizeMake(minSize.width, height)];
00678
00679 [view setHidden:NO];
00680 }
00681
00682 var remainingSpace = itemsWidth - minWidth,
00683 proportionate = 0.0;
00684
00685
00686
00687
00688 while (remainingSpace && [flexibleItemIndexes count])
00689 {
00690
00691 proportionate += remainingSpace / [flexibleItemIndexes count];
00692
00693
00694 remainingSpace = 0.0;
00695
00696 var index = CPNotFound;
00697
00698 while ((index = [flexibleItemIndexes indexGreaterThanIndex:index]) !== CPNotFound)
00699 {
00700 var item = _visibleItems[index],
00701 view = [self viewForItem:item],
00702 proposedWidth = [view minSize].width + proportionate,
00703 constrainedWidth = MIN(proposedWidth, [view maxSize].width);
00704
00705 if (constrainedWidth < proposedWidth)
00706 {
00707 [flexibleItemIndexes removeIndex:index];
00708
00709 remainingSpace += proposedWidth - constrainedWidth;
00710 }
00711
00712 [view setFrameSize:CGSizeMake(constrainedWidth, height)];
00713 }
00714 }
00715
00716
00717 var index = 0,
00718 count = _visibleItems.length,
00719 x = TOOLBAR_ITEM_MARGIN;
00720
00721 for (; index < count; ++index)
00722 {
00723 var view = [self viewForItem:_visibleItems[index]],
00724 viewWidth = CGRectGetWidth([view frame]);
00725
00726 [view setFrame:CGRectMake(x, 0.0, viewWidth, height)];
00727
00728 x += viewWidth + TOOLBAR_ITEM_MARGIN;
00729 }
00730
00731 var needsAdditionalItemsButton = NO;
00732
00733 if ([invisibleItemsSortedByPriority count])
00734 {
00735 var index = 0,
00736 count = [items count];
00737
00738 _invisibleItems = [];
00739
00740 for (; index < count; ++index)
00741 {
00742 var item = items[index];
00743
00744 if ([invisibleItemsSortedByPriority indexOfObjectIdenticalTo:item] !== CPNotFound)
00745 {
00746 [_invisibleItems addObject:item];
00747
00748 var identifier = [item itemIdentifier];
00749
00750 if (identifier !== CPToolbarSpaceItemIdentifier &&
00751 identifier !== CPToolbarFlexibleSpaceItemIdentifier &&
00752 identifier !== CPToolbarSeparatorItemIdentifier)
00753 needsAdditionalItemsButton = YES;
00754 }
00755 }
00756 }
00757
00758 if (needsAdditionalItemsButton)
00759 {
00760 [_additionalItemsButton setFrameOrigin:CGPointMake(itemsWidth + 5.0, (CGRectGetHeight([self bounds]) - CGRectGetHeight([_additionalItemsButton frame])) / 2.0)];
00761
00762 [self addSubview:_additionalItemsButton];
00763
00764 [_additionalItemsButton removeAllItems];
00765
00766 [_additionalItemsButton addItemWithTitle:@"Additional Items"];
00767 [[_additionalItemsButton itemArray][0] setImage:_CPToolbarViewExtraItemsImage];
00768
00769 var index = 0,
00770 count = [_invisibleItems count],
00771 hasNonSeparatorItem = NO;
00772
00773 for (; index < count; ++index)
00774 {
00775 var item = _invisibleItems[index],
00776 identifier = [item itemIdentifier];
00777
00778 if (identifier === CPToolbarSpaceItemIdentifier ||
00779 identifier === CPToolbarFlexibleSpaceItemIdentifier)
00780 continue;
00781
00782 if (identifier === CPToolbarSeparatorItemIdentifier)
00783 {
00784 if (hasNonSeparatorItem)
00785 [_additionalItemsButton addItem:[CPMenuItem separatorItem]];
00786
00787 continue;
00788 }
00789
00790 hasNonSeparatorItem = YES;
00791
00792 [_additionalItemsButton addItemWithTitle:[item label]];
00793
00794 var menuItem = [_additionalItemsButton itemArray][index + 1];
00795
00796 [menuItem setImage:[item image]];
00797
00798 [menuItem setTarget:[item target]];
00799 [menuItem setAction:[item action]];
00800 }
00801 }
00802 else
00803 [_additionalItemsButton removeFromSuperview];
00804 }
00805
00806 - (void)reloadToolbarItems
00807 {
00808
00809 var subviews = [self subviews],
00810 count = subviews.length;
00811
00812 while (count--)
00813 [subviews[count] removeFromSuperview];
00814
00815
00816 var items = [_toolbar items],
00817 index = 0;
00818
00819 count = items.length;
00820
00821 _minWidth = TOOLBAR_ITEM_MARGIN;
00822 _viewsForToolbarItems = { };
00823
00824 for (; index < count; ++index)
00825 {
00826 var item = items[index],
00827 view = [[_CPToolbarItemView alloc] initWithToolbarItem:item toolbar:self];
00828
00829 _viewsForToolbarItems[[item UID]] = view;
00830 [self addSubview:view];
00831
00832 _minWidth += [view minSize].width + TOOLBAR_ITEM_MARGIN;
00833 }
00834
00835 [self tile];
00836 }
00837
00838 @end
00839
00840
00841 var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
00842 {
00843 var lhsVisibilityPriority = [lhs visibilityPriority],
00844 rhsVisibilityPriority = [rhs visibilityPriority];
00845
00846 if (lhsVisibilityPriority == rhsVisibilityPriority)
00847 return CPOrderedSame;
00848
00849 if (lhsVisibilityPriority > rhsVisibilityPriority)
00850 return CPOrderedAscending;
00851
00852 return CPOrderedDescending;
00853 }
00854
00855 var TOP_MARGIN = 5.0,
00856 LABEL_MARGIN = 2.0;
00857
00858 @implementation _CPToolbarItemView : CPControl
00859 {
00860 CGSize _minSize @accessors(readonly, property=minSize);
00861 CGSize _maxSize @accessors(readonly, property=maxSize);
00862 CGSize _labelSize;
00863
00864 CPToolbarItem _toolbarItem;
00865 CPToolbar _toolbar;
00866
00867 CPImageView _imageView;
00868 CPView _view;
00869
00870 CPTextField _labelField;
00871
00872 BOOL _FIXME_isHUD;
00873 }
00874
00875 - (id)initWithToolbarItem:(CPToolbarItem)aToolbarItem toolbar:(CPToolbar)aToolbar
00876 {
00877 self = [super init];
00878
00879 if (self)
00880 {
00881 _toolbarItem = aToolbarItem;
00882
00883 _labelField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
00884
00885 [_labelField setFont:[CPFont systemFontOfSize:11.0]];
00886 [_labelField setTextColor:[self FIXME_labelColor]];
00887 [_labelField setTextShadowColor:[self FIXME_labelShadowColor]];
00888 [_labelField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
00889 [_labelField setAutoresizingMask:CPViewWidthSizable | CPViewMinXMargin];
00890
00891 [self addSubview:_labelField];
00892
00893 [self updateFromItem];
00894
00895 _toolbar = aToolbar;
00896
00897 var keyPaths = [@"label", @"image", @"alternateImage", @"minSize", @"maxSize", @"target", @"action", @"enabled"],
00898 index = 0,
00899 count = [keyPaths count];
00900
00901 for (; index < count; ++index)
00902 [_toolbarItem
00903 addObserver:self
00904 forKeyPath:keyPaths[index]
00905 options:0
00906 context:NULL];
00907 }
00908
00909 return self;
00910 }
00911
00912 - (void)FIXME_setIsHUD:(BOOL)shouldBeHUD
00913 {
00914 _FIXME_isHUD = shouldBeHUD;
00915 [_labelField setTextColor:[self FIXME_labelColor]];
00916 [_labelField setTextShadowColor:[self FIXME_labelShadowColor]];
00917 }
00918
00919 - (void)updateFromItem
00920 {
00921 var identifier = [_toolbarItem itemIdentifier];
00922
00923 if (identifier === CPToolbarSpaceItemIdentifier ||
00924 identifier === CPToolbarFlexibleSpaceItemIdentifier ||
00925 identifier === CPToolbarSeparatorItemIdentifier)
00926 {
00927 [_view removeFromSuperview];
00928 [_imageView removeFromSuperview];
00929
00930 _minSize = [_toolbarItem minSize];
00931 _maxSize = [_toolbarItem maxSize];
00932
00933 if (identifier === CPToolbarSeparatorItemIdentifier)
00934 {
00935 _view = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 2.0, 32.0)];
00936
00937
00938 sizes = {};
00939 sizes[@"CPToolbarItemSeparator"] = [CGSizeMake(2.0, 26.0), CGSizeMake(2.0, 1.0), CGSizeMake(2.0, 26.0)];
00940 [_view setBackgroundColor:_CPControlThreePartImagePattern(YES, sizes, @"CPToolbarItem", @"Separator")];
00941
00942 [self addSubview:_view];
00943 }
00944
00945 return;
00946 }
00947
00948 [self setTarget:[_toolbarItem target]];
00949 [self setAction:[_toolbarItem action]];
00950
00951 var view = [_toolbarItem view] || nil;
00952
00953 if (view !== _view)
00954 {
00955 if (!view)
00956 [_view removeFromSuperview];
00957
00958 else
00959 {
00960 [self addSubview:view];
00961 [_imageView removeFromSuperview];
00962 }
00963
00964 _view = view;
00965 }
00966
00967 if (!_view)
00968 {
00969 if (!_imageView)
00970 {
00971 _imageView = [[CPImageView alloc] initWithFrame:[self bounds]];
00972
00973 [_imageView setImageScaling:CPScaleNone];
00974
00975 [self addSubview:_imageView];
00976 }
00977
00978 [_imageView setImage:[_toolbarItem image]];
00979 }
00980
00981 var minSize = [_toolbarItem minSize],
00982 maxSize = [_toolbarItem maxSize];
00983
00984 [_labelField setStringValue:[_toolbarItem label]];
00985 [_labelField sizeToFit];
00986
00987 [self setEnabled:[_toolbarItem isEnabled]];
00988
00989 _labelSize = [_labelField frame].size;
00990
00991 _minSize = CGSizeMake(MAX(_labelSize.width, minSize.width), _labelSize.height + minSize.height + LABEL_MARGIN + TOP_MARGIN);
00992 _maxSize = CGSizeMake(MAX(_labelSize.width, minSize.width), 100000000.0);
00993
00994 [_toolbar tile];
00995 }
00996
00997 - (void)layoutSubviews
00998 {
00999 var identifier = [_toolbarItem itemIdentifier];
01000
01001 if (identifier === CPToolbarSpaceItemIdentifier ||
01002 identifier === CPToolbarFlexibleSpaceItemIdentifier)
01003 return;
01004
01005 var bounds = [self bounds],
01006 width = _CGRectGetWidth(bounds);
01007
01008 if (identifier === CPToolbarSeparatorItemIdentifier)
01009 return [_view setFrame:CGRectMake(ROUND((width - 2.0) / 2.0), 0.0, 2.0, _CGRectGetHeight(bounds))];
01010
01011 var view = _view || _imageView,
01012 itemMaxSize = [_toolbarItem maxSize],
01013 height = _CGRectGetHeight(bounds) - _labelSize.height - LABEL_MARGIN - TOP_MARGIN,
01014 viewWidth = MIN(itemMaxSize.width, width),
01015 viewHeight = MIN(itemMaxSize.height, height);
01016
01017 [view setFrame:CGRectMake( ROUND((width - viewWidth) / 2.0),
01018 TOP_MARGIN + ROUND((height - viewHeight) / 2.0),
01019 viewWidth,
01020 viewHeight)];
01021
01022 [_labelField setFrameOrigin:CGPointMake(ROUND((width - _labelSize.width) / 2.0), TOP_MARGIN + height + LABEL_MARGIN)];
01023 }
01024
01025 - (void)mouseDown:(CPEvent)anEvent
01026 {
01027 if ([_toolbarItem view])
01028 return [[self nextResponder] mouseDown:anEvent];
01029
01030 var identifier = [_toolbarItem itemIdentifier];
01031
01032 if (identifier === CPToolbarSpaceItemIdentifier ||
01033 identifier === CPToolbarFlexibleSpaceItemIdentifier ||
01034 identifier === CPToolbarSeparatorItemIdentifier)
01035 return [[self nextResponder] mouseDown:anEvent];
01036
01037 [super mouseDown:anEvent];
01038 }
01039
01040 - (void)setEnabled:(BOOL)shouldBeEnabled
01041 {
01042 [super setEnabled:shouldBeEnabled];
01043
01044 if (shouldBeEnabled)
01045 {
01046 [_imageView setAlphaValue:1.0];
01047 [_labelField setAlphaValue:1.0];
01048 }
01049 else
01050 {
01051 [_imageView setAlphaValue:0.5];
01052 [_labelField setAlphaValue:0.5];
01053 }
01054 }
01055
01056 - (CPColor)FIXME_labelColor
01057 {
01058 if (_FIXME_isHUD)
01059 return [CPColor whiteColor];
01060
01061 return [CPColor blackColor];
01062 }
01063
01064 - (CPColor)FIXME_labelShadowColor
01065 {
01066 if (_FIXME_isHUD)
01067 return [self isHighlighted] ? [CPColor colorWithWhite:1.0 alpha:0.5] : [CPColor clearColor];
01068
01069 return [self isHighlighted] ? [CPColor colorWithWhite:0.0 alpha:0.3] : [CPColor colorWithWhite:1.0 alpha:0.75];
01070 }
01071
01072 - (void)setHighlighted:(BOOL)shouldBeHighlighted
01073 {
01074 [super setHighlighted:shouldBeHighlighted];
01075
01076 if (shouldBeHighlighted)
01077 {
01078 var alternateImage = [_toolbarItem alternateImage];
01079
01080 if (alternateImage)
01081 [_imageView setImage:alternateImage];
01082
01083 [_labelField setTextShadowOffset:CGSizeMakeZero()];
01084 }
01085 else
01086 {
01087 var image = [_toolbarItem image];
01088
01089 if (image)
01090 [_imageView setImage:image];
01091
01092 [_labelField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
01093 }
01094
01095 [_labelField setTextShadowColor:[self FIXME_labelShadowColor]];
01096 }
01097
01098 - (void)sendAction:(SEL)anAction to:(id)aSender
01099 {
01100 [CPApp sendAction:anAction to:aSender from:_toolbarItem];
01101 }
01102
01103 - (void)observeValueForKeyPath:(CPString)aKeyPath
01104 ofObject:(id)anObject
01105 change:(CPDictionary)aChange
01106 context:(id)aContext
01107 {
01108 if (aKeyPath === "enabled")
01109 [self setEnabled:[anObject isEnabled]];
01110
01111 else if (aKeyPath === @"target")
01112 [self setTarget:[anObject target]];
01113
01114 else if (aKeyPath === @"action")
01115 [self setAction:[anObject action]];
01116
01117 else
01118 [self updateFromItem];
01119 }
01120
01121 @end