// // KMToolbar.m // SignFlow // // Copyright © 2022 Kdan Mobile. All rights reserved. // #import "KMToolbar.h" #import #import NSString *KMNewToolbarSpaceItemIdentifier = @"KMNewToolbarSpaceItemIdentifier"; NSString *KMToolbarDividerItemIdentifier = @"KMToolbarDividerItemIdentifier"; #define KMToolbarSpaceItemWidth 30.0 #define KMToolbarLineItemWidth 1.0 #define KMToolbarItemSpace (6.0+2.0) #pragma mark - KMToolbarClickButton @implementation KMToolbarClickButton @end #pragma mark - KMToolBoxItem @interface KMToolBoxItem() @property(nonatomic,retain) NSBox *imageViewBox; @property(nonatomic,retain) NSButton *imageViewBtn; @property(nonatomic,retain) NSButton *nameBtn; @property(nonatomic,retain) KMToolbarClickButton *clickButton; @property(nonatomic,retain) NSButton *needExpandButton; @property (nonatomic,retain) NSPopover *popOver; @property (nonatomic,retain) KMCustomButtonPopMenuViewController *menuViewController; @property (nonatomic,retain) NSString *itemIdentifier; @property (nonatomic,retain) NSImage *kNormalImage; @property (nonatomic,retain) NSString *originalHelpTip; @end @implementation KMToolBoxItem - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)drawRect:(NSRect)dirtyRect { if ([self.itemIdentifier isEqual:KMToolbarDividerItemIdentifier]) { CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; CGContextSaveGState(context); CGContextTranslateCTM(context, CGRectGetWidth(dirtyRect)/2., CGRectGetHeight(dirtyRect)/2. - 10); CGContextMoveToPoint(context, 0, 0); CGContextAddLineToPoint(context, 0, 20); CGContextSetStrokeColorWithColor(context, [NSColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor); CGContextStrokePath(context); CGContextRestoreGState(context); } } - (instancetype)initWithItemIdentifier:(NSString *)itemIdentifier postition:(KMToolBoxImagePosition)imagePositionImagePosition withPopMenu:(KMCustomButtonPopMenuViewController *)popMenuViewController { if (self == [super init]) { self.boxImagePosition = imagePositionImagePosition; self.menuViewController = popMenuViewController; self.itemIdentifier = itemIdentifier; self.wantsLayer = YES; self.layer.cornerRadius = 4; self.layer.masksToBounds = YES; self.normalBackgroundColor = [NSColor clearColor]; self.selectedBackgroundColor = [NSColor colorWithRed:223.0/255.0 green:225.0/255.0 blue:229.0/255.0 alpha:1]; [self addTrackingArea]; [self layoutView]; if (popMenuViewController) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowClosedPop:) name:@"KMPopOverClosedByWindowNotification" object:nil]; } } return self; } - (instancetype)initWithItemIdentifier:(NSString *)itemIdentifier { if (self == [super init]) { self.itemIdentifier = itemIdentifier; self.boxImagePosition = KMToolBoxImagePosition_Left; self.wantsLayer = YES; self.layer.cornerRadius = 5; self.layer.masksToBounds = YES; self.normalBackgroundColor = [NSColor clearColor]; self.selectedBackgroundColor = [NSColor colorWithRed:223.0/255.0 green:225.0/255.0 blue:229.0/255.0 alpha:1]; [self addTrackingArea]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowClosedPop:) name:@"KMPopOverClosedByWindowNotification" object:nil]; } return self; } #pragma mark - View - (void)layoutView { CGFloat offset = 4; CGFloat offsetY = 2; CGFloat offsetX = 4; if ([self.nameBtn superview]) { [self.nameBtn removeFromSuperview]; } if ([self.linView superview]) { [self.linView removeFromSuperview]; } if([self.imageViewBox superview]) { [self.imageViewBox removeFromSuperview]; } if([self.imageViewBtn superview]) { [self.imageViewBtn removeFromSuperview]; } if(self.customizeView) { if([self.customizeView superview]) { [self.customizeView removeFromSuperview]; } [self addSubview:self.customizeView]; [self.customizeView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(@0); make.centerY.equalTo(@0); make.width.offset(self.customizeView.frame.size.width); make.height.offset(self.customizeView.frame.size.height); }]; return; } if (KMToolBoxImagePosition_Only == self.boxImagePosition && ![self.itemIdentifier isEqual:KMToolbarDividerItemIdentifier]) { [self addSubview:self.imageViewBox]; [self.imageViewBox mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.top.bottom.equalTo(@0); }]; [self.imageViewBox.contentView addSubview:self.imageViewBtn]; [self.imageViewBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.imageViewBox.mas_left).offset(offsetX); make.top.equalTo(self.imageViewBox.mas_top).offset(offsetY); make.bottom.equalTo(self.imageViewBox.mas_bottom).offset(-offsetY); make.right.equalTo(self.imageViewBox.mas_right).offset(-offsetX); }]; } else if (KMToolBoxImagePosition_Left == self.boxImagePosition) { [self addSubview:self.imageViewBox]; [self.imageViewBox mas_makeConstraints:^(MASConstraintMaker *make) { make.left.top.bottom.equalTo(@0); }]; [self.imageViewBox.contentView addSubview:self.imageViewBtn]; [self.imageViewBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(@0); make.left.equalTo(self.imageViewBox.mas_left).offset(2 * offsetX); make.top.equalTo(self.imageViewBox.mas_top).offset(offsetY); make.bottom.equalTo(self.imageViewBox.mas_bottom).offset(-offsetY); }]; [self addSubview:self.nameBtn]; [self.nameBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(@0); make.left.equalTo(self.imageViewBox.mas_right).offset(0); if(self.needExpandAction) { make.right.equalTo(self.mas_right).offset(- 2 * offsetX-8); } else { make.right.equalTo(self.mas_right).offset(- 2 * offsetX); } }]; if(self.needExpandAction) { self.needExpandButton.image = [NSImage imageNamed:@"KMImageNameUXIconBtnTriDownNor"]; [self addSubview:self.needExpandButton]; [self.needExpandButton mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(@0); make.width.height.equalTo(@8); make.right.equalTo(self.mas_right).offset(-offset); }]; } self.layer.cornerRadius = 6; } else if (KMToolBoxImagePosition_ExpandLeft == self.boxImagePosition) { [self addSubview:self.imageViewBox]; [self.imageViewBox mas_makeConstraints:^(MASConstraintMaker *make) { make.left.top.bottom.equalTo(@0); }]; [self.imageViewBox.contentView addSubview:self.imageViewBtn]; [self.imageViewBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(@0); make.left.equalTo(self.imageViewBox.mas_left).offset(offsetX); make.top.equalTo(self.imageViewBox.mas_top).offset(offsetY); make.bottom.equalTo(self.imageViewBox.mas_bottom).offset(-offsetY); }]; self.needExpandButton.image = [NSImage imageNamed:@"KMImageNameUXIconBtnTriDownNor"]; [self addSubview:self.needExpandButton]; [self.needExpandButton mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(@0); make.width.height.equalTo(@8); make.right.equalTo(self.mas_right).offset(-offsetX); }]; [self addSubview:self.nameBtn]; [self.nameBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(@0); make.left.equalTo(self.imageViewBox.mas_right).offset(0); make.right.equalTo(self.needExpandButton.mas_left).offset(0); }]; } else if(KMToolBoxImagePosition_Above == self.boxImagePosition){ [self addSubview:self.nameBtn]; self.nameBtn.alignment = NSTextAlignmentCenter; [self.nameBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(@0); make.width.greaterThanOrEqualTo(@32); make.bottom.equalTo(self.mas_bottom).offset(0); }]; [self addSubview:self.imageViewBox]; [self.imageViewBox mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@0); make.width.equalTo(@32); make.centerX.equalTo(@0); make.bottom.equalTo(self.nameBtn.mas_top).offset(0); }]; [self.imageViewBox.contentView addSubview:self.imageViewBtn]; [self.imageViewBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.left.top.right.equalTo(@(offset)); make.bottom.right.equalTo(@(-offset)); }]; } if([self.nameBtn superview] && self.isMainTool) { [self addSubview:self.linView]; [self.linView mas_makeConstraints:^(MASConstraintMaker *make) { make.width.offset(32); make.height.offset(3); make.centerX.equalTo(self.mas_centerX); make.bottom.equalTo(self.mas_bottom).offset(0); }]; _nameBtn.font = [NSFont systemFontOfSize:14.0]; self.linView.hidden = YES; } else { _nameBtn.font = [NSFont systemFontOfSize:12.0]; } if (![self.itemIdentifier isEqual:KMToolbarDividerItemIdentifier]) { self.imageViewBox.borderColor = [NSColor clearColor]; self.imageViewBox.borderWidth = 1.0; self.imageViewBox.cornerRadius = 7.0; [self addSubview:self.clickButton]; [self.clickButton mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.top.bottom.equalTo(@0); }]; } } #pragma mark - Get&Set - (void)setBoxImagePosition:(KMToolBoxImagePosition)boxImagePosition { _boxImagePosition = boxImagePosition; [self layoutView]; } - (void)setCustomizeView:(NSView *)customizeView { _customizeView = customizeView; [self layoutView]; } - (void)setIsSelected:(BOOL)isSelected { _isSelected = isSelected; if (![self.itemIdentifier isEqual: KMToolbarDividerItemIdentifier]) { if (isSelected) { if (_isMainTool) { self.layer.backgroundColor = self.normalBackgroundColor.CGColor; [self.nameBtn setTitleColorWithColor:[KMAppearance titleColor] font:[NSFont fontWithName:@"SFProText-Semibold" size:14]]; self.linView.hidden = NO; return; } self.layer.backgroundColor = self.selectedBackgroundColor.CGColor; if(self.image && self.alternateImage) { if (self.selectedImage) { self.imageViewBtn.image = self.selectedImage; } else { self.imageViewBtn.image = self.alternateImage; } } if(self.nameBtn.superview) { [self.nameBtn setTitleColorWithColor:[KMAppearance titleColor] font:nil]; } if(self.needExpandAction) { self.needExpandButton.image = [NSImage imageNamed:@"KMImageNameUXIconBtnTriDownSel"]; } } else { if (_isMainTool) { self.layer.backgroundColor = self.normalBackgroundColor.CGColor; [self.nameBtn setTitleColorWithColor:[NSColor colorWithRed:97.0/255.0 green:100.0/255.0 blue:105.0/255.0 alpha:1] font:[NSFont fontWithName:@"SFProText-Regular" size:14]]; self.linView.hidden = YES; return; } self.layer.backgroundColor = self.normalBackgroundColor.CGColor; if(self.needExpandAction) { self.needExpandButton.image = [NSImage imageNamed:@"KMImageNameUXIconBtnTriDownNor"]; } if(self.image) { self.imageViewBtn.image = self.image; } if(self.nameBtn.superview) { [self.nameBtn setTitleColorWithColor:[KMAppearance titleColor] font:nil]; } } } } - (void)setIsMainTool:(BOOL)isMainTool { _isMainTool = isMainTool; if (_isMainTool) { [self.nameBtn setTitleColorWithColor:[NSColor colorWithRed:97.0/255.0 green:100.0/255.0 blue:105.0/255.0 alpha:1] font:[NSFont fontWithName:@"SFProText-Regular" size:14]]; } else { [self.nameBtn setTitleColorWithColor:[KMAppearance titleColor] font:nil]; } [self layoutView]; } - (void)setPopOver:(NSPopover *)popOver { if (![_popOver isEqual:popOver]) { _popOver = popOver; if (popOver) { self.layer.backgroundColor = self.selectedBackgroundColor.CGColor; } else { if (self.isSelected) { self.layer.backgroundColor = self.selectedBackgroundColor.CGColor; }else { self.layer.backgroundColor = self.normalBackgroundColor.CGColor; } } } } - (NSButton *)imageViewBtn { if (!_imageViewBtn) { _imageViewBtn = [[NSButton alloc] init]; _imageViewBtn.bezelStyle = NSBezelStyleRegularSquare; _imageViewBtn.bordered = NO; _imageViewBtn.imagePosition = NSImageOnly; } return _imageViewBtn; } - (KMToolbarClickButton *)clickButton { if (!_clickButton) { _clickButton = [[KMToolbarClickButton alloc] init]; _clickButton.bezelStyle = NSBezelStyleRegularSquare; _clickButton.bordered = NO; _clickButton.imagePosition = NSImageOnly; _clickButton.clickObject = self; } return _clickButton; } - (NSButton *)needExpandButton { if (!_needExpandButton) { _needExpandButton = [[NSButton alloc] init]; _needExpandButton.bezelStyle = NSBezelStyleRegularSquare; _needExpandButton.bordered = NO; _needExpandButton.image = [NSImage imageNamed:@"KMImageNameUXIconBtnTriDownNor"]; _needExpandButton.imagePosition = NSImageOnly; } return _needExpandButton; } - (NSButton *)nameBtn { if (!_nameBtn) { _nameBtn = [[NSButton alloc] init]; _nameBtn.bezelStyle = NSBezelStyleRegularSquare; _nameBtn.bordered = NO; _nameBtn.imagePosition = NSNoImage; _nameBtn.font = [NSFont systemFontOfSize:12.0]; [_nameBtn setTitle:_titleName ? : @" "]; } return _nameBtn; } -(NSBox *)imageViewBox { if (!_imageViewBox) { _imageViewBox = [[NSBox alloc] init]; [_imageViewBox setBorderWidth:0.0f]; _imageViewBox.contentViewMargins = NSMakeSize(0, 0); _imageViewBox.boxType = NSBoxCustom; } return _imageViewBox; } - (NSView *)linView { if (!_linView) { _linView = [[NSView alloc] init]; _linView.wantsLayer = YES; _linView.layer.backgroundColor = [NSColor colorWithRed:23.0/255.0 green:112.0/255.0 blue:244.0/255.0 alpha:1].CGColor; _linView.layer.cornerRadius = 2.0; } return _linView; } -(void)setImage:(NSImage *)image { if (image != _image) { _image = image; } self.imageViewBtn.image = image; } -(void)setTitleName:(NSString *)titleName { if (titleName != _titleName) { _titleName = titleName; } self.nameBtn.title = titleName ? : KMToolbarDividerItemIdentifier; [self.nameBtn setTitleColorWithColor:[KMAppearance titleColor] font:nil]; } - (void)setTarget:(id)target { _target = target; self.clickButton.target = target; } - (void)setBtnTag:(NSInteger)btnTag { _btnTag = btnTag; self.clickButton.tag = btnTag; } - (void)setBtnAction:(SEL)btnAction { _btnAction = btnAction; self.clickButton.action = btnAction; } -(void)setToolTip:(NSString *)toolTip { self.clickButton.toolTip = toolTip?:@""; self.originalHelpTip = self.clickButton.toolTip; if(self.isShowCustomToolTip) { self.clickButton.toolTip = @""; } } - (void)setIsShowCustomToolTip:(BOOL)isShowCustomToolTip { _isShowCustomToolTip = isShowCustomToolTip; if(isShowCustomToolTip) { self.clickButton.toolTip = @""; } } - (void)setUnEnabled:(BOOL)unEnabled { if (unEnabled) { self.clickButton.enabled = NO; self.nameBtn.enabled = NO; self.imageViewBtn.enabled = NO; self.needExpandButton.enabled = NO; } else { self.clickButton.enabled = YES; self.nameBtn.enabled = YES; self.imageViewBtn.enabled = YES; self.needExpandButton.enabled = YES; } } #pragma mark - Private - (void)addTrackingArea { NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect | NSTrackingActiveInKeyWindow owner:self userInfo:nil]; [self addTrackingArea:trackingArea]; } - (void)mouseEntered:(NSEvent *)event { [super mouseEntered:event]; if (![self.window isKeyWindow]) { return; } if ([self.itemIdentifier isEqualToString:KMToolbarDividerItemIdentifier] || self.customizeView || self.image == nil) { return; } if (!self.isSelected) { self.layer.backgroundColor = self.selectedBackgroundColor.CGColor; if(self.image && self.alternateImage) { self.kNormalImage = self.image; self.imageViewBtn.image = self.alternateImage; if(self.nameBtn.superview) { [self.nameBtn setTitleColorWithColor:[KMAppearance titleColor] font:nil]; } } } if (self.needExpandAction) { self.needExpandButton.image = [NSImage imageNamed:@"KMImageNameUXIconBtnTriDownSel"]; [self showPop:self]; }else if (_isShowCustomToolTip) { [self performSelector:@selector(showHUDHint) withObject:nil afterDelay:0.1]; } } - (void)mouseExited:(NSEvent *)event { [super mouseExited:event]; if (!_isSelected && !self.needExpandAction) { self.layer.backgroundColor = self.normalBackgroundColor.CGColor; if(self.image && self.alternateImage) { self.imageViewBtn.image = self.kNormalImage ? : self.image; } } if(self.needExpandAction && !_isSelected) { self.layer.backgroundColor = self.normalBackgroundColor.CGColor; if(self.image && self.alternateImage) { self.imageViewBtn.image = self.kNormalImage ? : self.image; } self.needExpandButton.image = [NSImage imageNamed:@"KMImageNameUXIconBtnTriDownNor"]; } if (![self.window isKeyWindow]) { return; } if(self.nameBtn.superview && !_isSelected && !_isMainTool) { [self.nameBtn setTitleColorWithColor:[KMAppearance titleColor] font:nil]; } if (_isShowCustomToolTip && !self.needExpandAction) { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showHUDHint) object:nil]; [self closePop]; } } - (void)showPop:(NSView *)sender { } - (void)showHUDHint { // KMToolbarItemPopViewController *popViewController = [[[KMToolbarItemPopViewController alloc] init] autorelease]; // self.popOver = [[[NSPopover alloc] init] autorelease]; // self.popOver.contentViewController = popViewController; // self.popOver.animates = NO; // self.popOver.behavior = NSPopoverBehaviorSemitransient; // self.popOver.backgroundColor = [KMAppearance KMBluegrey01Color]; // // self.popOver.contentSize = popViewController.view.frame.size; // [popViewController updateWithHelpTip:self.originalHelpTip]; // [self.popOver showRelativeToRect:self.bounds ofView:self preferredEdge:NSRectEdgeMinY]; } - (void)windowClosedPop:(NSNotification *)sender { if ([sender.object isEqual:self.popOver]) { self.popOver = nil; } } - (void)closePop { [self.popOver close]; self.popOver = nil; } @end #pragma mark - KMNewToolbar @interface KMToolbar () @property (nonatomic,retain) NSString *toolbarIdentifier; @property (nonatomic,retain) NSArray *items; @property (nonatomic,retain) NSArray *visibleItems; @property (nonatomic,retain) NSMutableArray *invisibleItems; @property (nonatomic,retain) NSView *contentView; @property (nonatomic,retain) NSButton *moreButton; @end @implementation KMToolbar #pragma mark - Init Methods - (instancetype)initWithIdentifier:(NSString *)identifier { if (self = [super init]) { self.toolbarIdentifier = identifier; [self addTrackingArea]; } return self; } - (instancetype)initWithCoder:(NSCoder *)decoder { if (self = [super initWithCoder:decoder]) { self.wantsLayer = YES; self.layer.backgroundColor = [NSColor clearColor].CGColor; [self addTrackingArea]; } return self; } - (instancetype)initWithFrame:(NSRect)frameRect { if (self = [super initWithFrame:frameRect]) { self.wantsLayer = YES; self.layer.backgroundColor = [NSColor clearColor].CGColor; [self addTrackingArea]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } -(void)mouseMoved:(NSEvent *)event { [self.window mouseMoved:event]; [super mouseMoved:event]; } - (void)addTrackingArea { NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options: NSTrackingInVisibleRect | NSTrackingActiveInKeyWindow | NSTrackingMouseMoved owner:self userInfo:nil]; [self addTrackingArea:trackingArea]; } #pragma mark - Private Methods - (NSButton *)moreButton { if (!_moreButton) { _moreButton = [[NSButton alloc] init]; _moreButton.bezelStyle = NSBezelStyleRegularSquare; _moreButton.bordered = NO; _moreButton.font = [NSFont systemFontOfSize:20]; _moreButton.title = @" »"; _moreButton.hidden = YES; _moreButton.target = self; _moreButton.action = @selector(moreButtonAction:); _moreButton.wantsLayer = YES; _moreButton.layer.backgroundColor = [NSColor colorWithRed:223.0/255.0 green:225.0/255.0 blue:229.0/255.0 alpha:1].CGColor; } return _moreButton; } - (void)moreButtonAction:(id)sender { NSMenu *menu = [[NSMenu alloc] init]; for (KMToolBoxItem *item in self.invisibleItems) { if ([item.itemIdentifier isEqualToString:KMToolbarDividerItemIdentifier]) { [menu addItem:[NSMenuItem separatorItem]]; } else if (item.menuFormRepresentation) { [menu addItem:item.menuFormRepresentation]; } } [menu popUpMenuPositioningItem:menu.itemArray.firstObject atLocation:NSMakePoint(CGRectGetMaxX(self.moreButton.frame), CGRectGetMaxY(self.moreButton.frame)-5) inView:self]; } - (NSView *)contentView { if (!_contentView) { _contentView = [[NSView alloc] init]; } return _contentView; } - (void)updateMainView { NSView *centerView = [[NSView alloc] init]; [self addSubview:centerView]; NSView *leftView = [[NSView alloc] init]; leftView.wantsLayer = YES; leftView.layer.backgroundColor = [NSColor colorWithRed:247/255.f green:248/255.f blue:250/255.f alpha:1.f].CGColor; [self addSubview:leftView]; [leftView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.mas_left).offset(0); make.top.equalTo(self.mas_top).offset(0); make.bottom.equalTo(self.mas_bottom).offset(0); }]; NSArray *leftitemIdentifiers = nil; if ([self.delegate respondsToSelector:@selector(toolbarLeftDefaultItemIdentifiers:)]) { leftitemIdentifiers = [self.delegate toolbarLeftDefaultItemIdentifiers:self]; } KMToolBoxItem *leftlastItem = nil; for (NSUInteger i=0; i< leftitemIdentifiers.count; i++) { NSString *itemIdentifier = leftitemIdentifiers[i]; if (![itemIdentifier isKindOfClass:[NSString class]]) { return; } KMToolBoxItem *item = nil; if ([itemIdentifier isEqualToString:KMToolbarDividerItemIdentifier]) { item = [[KMToolBoxItem alloc] initWithItemIdentifier:itemIdentifier postition:KMToolBoxImagePosition_Only withPopMenu:nil]; } else if ([itemIdentifier isEqualToString:KMNewToolbarSpaceItemIdentifier]) { item = [[KMToolBoxItem alloc] initWithItemIdentifier:itemIdentifier postition:KMToolBoxImagePosition_Only withPopMenu:nil]; item.layer.backgroundColor = [NSColor clearColor].CGColor; item.imageViewBox.borderColor = [NSColor clearColor]; item.layer.cornerRadius = 0.0; } else if ([self.delegate respondsToSelector:@selector(toolbar:itemForItemIdentifier:)]) { item = [self.delegate toolbar:self itemForItemIdentifier:itemIdentifier]; } if (!item) { continue; } [leftView addSubview:item]; if (leftlastItem) { if (i == leftitemIdentifiers.count - 1) { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@10); make.bottom.equalTo(@(-10)); make.left.equalTo(leftlastItem.mas_right).offset(KMToolbarItemSpace); make.right.equalTo(leftView.mas_right).offset(0); }]; } else { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@10); make.bottom.equalTo(@(-10)); make.left.equalTo(leftlastItem.mas_right).offset(KMToolbarItemSpace); }]; } } else { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@10); make.bottom.equalTo(@(-10)); make.left.equalTo(@20); }]; } leftlastItem = item; } NSView *rightView = [[NSView alloc] init]; [self addSubview:rightView]; rightView.wantsLayer = YES; rightView.layer.backgroundColor = [NSColor colorWithRed:247/255.f green:248/255.f blue:250/255.f alpha:1.f].CGColor; [rightView mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.mas_right).offset(0); make.top.equalTo(self.mas_top).offset(0); make.bottom.equalTo(self.mas_bottom).offset(0); }]; NSArray *rightitemIdentifiers = nil; if ([self.delegate respondsToSelector:@selector(toolbarRightDefaultItemIdentifiers:)]) { rightitemIdentifiers = [self.delegate toolbarRightDefaultItemIdentifiers:self]; } KMToolBoxItem *rightlastItem = nil; for (NSUInteger i=0; i< rightitemIdentifiers.count; i++) { NSString *itemIdentifier = rightitemIdentifiers[i]; if (![itemIdentifier isKindOfClass:[NSString class]]) { return; } KMToolBoxItem *item = nil; if ([itemIdentifier isEqualToString:KMToolbarDividerItemIdentifier]) { item = [[KMToolBoxItem alloc] initWithItemIdentifier:itemIdentifier postition:KMToolBoxImagePosition_Only withPopMenu:nil]; } else if ([itemIdentifier isEqualToString:KMNewToolbarSpaceItemIdentifier]) { item = [[KMToolBoxItem alloc] initWithItemIdentifier:itemIdentifier postition:KMToolBoxImagePosition_Only withPopMenu:nil]; item.layer.backgroundColor = [NSColor clearColor].CGColor; item.imageViewBox.borderColor = [NSColor clearColor]; item.layer.cornerRadius = 0.0; } else if ([self.delegate respondsToSelector:@selector(toolbar:itemForItemIdentifier:)]) { item = [self.delegate toolbar:self itemForItemIdentifier:itemIdentifier]; } if (!item) { continue; } [rightView addSubview:item]; if (rightlastItem) { if (i == rightitemIdentifiers.count - 1) { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@6); make.bottom.equalTo(@(-6)); make.left.equalTo(rightlastItem.mas_right).offset(KMToolbarItemSpace); make.right.equalTo(rightView.mas_right).offset(-20); }]; } else { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@6); make.bottom.equalTo(@(-6)); make.left.equalTo(rightlastItem.mas_right).offset(KMToolbarItemSpace); }]; } } else { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@6); make.bottom.equalTo(@(-6)); make.left.equalTo(@0); }]; } rightlastItem = item; } // NSView *centerView = [[NSView alloc] init]; // [self addSubview:centerView]; [centerView mas_makeConstraints:^(MASConstraintMaker *make) { // make.right.equalTo(rightView.mas_left).offset(0); make.right.mas_equalTo(0); make.top.equalTo(self.mas_top).offset(0); make.bottom.equalTo(self.mas_bottom).offset(0); // make.left.equalTo(leftView.mas_right).offset(0); make.left.mas_equalTo(0); }]; if(!self.contentView.superview) { [centerView addSubview:self.contentView]; [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(@0); make.centerY.equalTo(@0); }]; } for (KMToolBoxItem *item in self.items) { [item removeFromSuperview]; } self.items = nil; CGFloat posX = 0; NSMutableArray *items = [NSMutableArray array]; NSArray *itemIdentifiers = nil; if ([self.delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)]) { itemIdentifiers = [self.delegate toolbarDefaultItemIdentifiers:self]; } KMToolBoxItem *lastItem = nil; for (NSUInteger i=0; i< itemIdentifiers.count - self.invisibleItems.count; i++) { NSString *itemIdentifier = itemIdentifiers[i]; if (![itemIdentifier isKindOfClass:[NSString class]]) { return; } KMToolBoxItem *item = nil; if ([itemIdentifier isEqualToString:KMToolbarDividerItemIdentifier]) { item = [[KMToolBoxItem alloc] initWithItemIdentifier:itemIdentifier postition:KMToolBoxImagePosition_Only withPopMenu:nil]; } else if ([itemIdentifier isEqualToString:KMNewToolbarSpaceItemIdentifier]) { item = [[KMToolBoxItem alloc] initWithItemIdentifier:itemIdentifier postition:KMToolBoxImagePosition_Only withPopMenu:nil]; item.layer.backgroundColor = [NSColor clearColor].CGColor; item.imageViewBox.borderColor = [NSColor clearColor]; item.layer.cornerRadius = 0.0; } else if ([self.delegate respondsToSelector:@selector(toolbar:itemForItemIdentifier:)]) { item = [self.delegate toolbar:self itemForItemIdentifier:itemIdentifier]; } if (!item) { continue; } [self.contentView addSubview:item]; if (lastItem) { if (i == itemIdentifiers.count - 1) { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.left.equalTo(lastItem.mas_right).offset(KMToolbarItemSpace); make.right.equalTo(self.contentView.mas_right).offset(0); }]; } else { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.left.equalTo(lastItem.mas_right).offset(KMToolbarItemSpace); }]; } } else { if (item.image) { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.left.equalTo(@0); }]; } else { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.left.equalTo(@0); make.height.offset(40); }]; } } [items addObject:item]; lastItem = item; posX += item.frame.size.width; } self.items = items; [self addSubview:self.moreButton]; } // UI 20 16 // item w 28 h 24 - (void)updateView { if(!self.contentView.superview) { [self addSubview:self.contentView]; [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(@0); make.centerY.equalTo(@0); }]; } for (KMToolBoxItem *item in self.items) { [item removeFromSuperview]; } self.items = nil; CGFloat posX = 0; NSMutableArray *items = [NSMutableArray array]; NSArray *itemIdentifiers = nil; if ([self.delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)]) { itemIdentifiers = [self.delegate toolbarDefaultItemIdentifiers:self]; } KMToolBoxItem *lastItem = nil; for (NSUInteger i=0; i< itemIdentifiers.count - self.invisibleItems.count; i++) { NSString *itemIdentifier = itemIdentifiers[i]; if (![itemIdentifier isKindOfClass:[NSString class]]) { return; } KMToolBoxItem *item = nil; if ([itemIdentifier isEqualToString:KMToolbarDividerItemIdentifier]) { item = [[KMToolBoxItem alloc] initWithItemIdentifier:itemIdentifier postition:KMToolBoxImagePosition_Only withPopMenu:nil]; } else if ([itemIdentifier isEqualToString:KMNewToolbarSpaceItemIdentifier]) { item = [[KMToolBoxItem alloc] initWithItemIdentifier:itemIdentifier postition:KMToolBoxImagePosition_Only withPopMenu:nil]; item.layer.backgroundColor = [NSColor clearColor].CGColor; item.imageViewBox.borderColor = [NSColor clearColor]; item.layer.cornerRadius = 0.0; } else if ([self.delegate respondsToSelector:@selector(toolbar:itemForItemIdentifier:)]) { item = [self.delegate toolbar:self itemForItemIdentifier:itemIdentifier]; } if (!item) { continue; } [self.contentView addSubview:item]; if (lastItem) { if (i == itemIdentifiers.count - 1) { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.left.equalTo(lastItem.mas_right).offset(KMToolbarItemSpace); make.right.equalTo(self.contentView.mas_right).offset(0); }]; } else { if ([itemIdentifier isEqualToString:KMNewToolbarSpaceItemIdentifier]) { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.left.equalTo(lastItem.mas_right).offset(2); }]; } else { if ([lastItem.itemIdentifier isEqualToString:KMNewToolbarSpaceItemIdentifier]) { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.left.equalTo(lastItem.mas_right).offset(2); }]; } else { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.left.equalTo(lastItem.mas_right).offset(KMToolbarItemSpace); }]; } } } } else { if (item.image) { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.left.equalTo(@0); }]; } else { [item mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.left.equalTo(@0); make.height.offset(40); }]; } } [items addObject:item]; lastItem = item; posX += item.frame.size.width; } self.items = items; [self addSubview:self.moreButton]; } - (void)updateLayer { [super updateLayer]; self.layer.backgroundColor = NSColor.clearColor.CGColor; } #pragma mark - View Methods - (void)viewWillMoveToWindow:(NSWindow *)newWindow { [super viewWillMoveToWindow:newWindow]; if (newWindow && !_contentView) { NSArray *leftitemIdentifiers = nil; if ([self.delegate respondsToSelector:@selector(toolbarLeftDefaultItemIdentifiers:)]) { leftitemIdentifiers = [self.delegate toolbarLeftDefaultItemIdentifiers:self]; } if (leftitemIdentifiers.count >0) { [self updateMainView]; }else { [self updateView]; } [self resizeSubviewsWithOldSize:self.frame.size]; // // [[NSNotificationCenter defaultCenter] addObserver:self // selector:@selector(toolbarCustomChangeNotification:) // name:KMToolbarCustomChangeNotification // object:nil]; NSBox *topLine = [[NSBox alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 0.5)]; topLine.boxType = NSBoxSeparator; topLine.fillColor = NSColor.blackColor; [self addSubview:topLine]; [topLine mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(self); make.bottom.equalTo(self.mas_bottom).offset(-(0.5)); make.height.offset(0.5); }]; NSBox *bottomLine = [[NSBox alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 0.5)]; bottomLine.boxType = NSBoxSeparator; bottomLine.fillColor = NSColor.blackColor; [self addSubview:bottomLine]; [bottomLine mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(self); make.top.equalTo(self.mas_top).offset(0.1); make.height.offset(0.5); }]; }; if (newWindow) { [self addTrackingArea]; } } - (void)resizeSubviewsWithOldSize:(NSSize)oldSize { [super resizeSubviewsWithOldSize:oldSize]; if (!_contentView) { return; } CGFloat moreButtonWidth = 30; CGFloat leftButtonWidth = 10; NSRect frame = self.contentView.frame; __block NSUInteger count = self.items.count; [self.items enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { KMToolBoxItem *item = (KMToolBoxItem *)obj; if (CGRectGetMaxX(item.frame) <= self.frame.size.width-moreButtonWidth-leftButtonWidth) { count = idx; *stop = YES; } }]; if (count >= self.items.count) { return; } frame.size.width = CGRectGetMaxX([self.items[count] frame]); if (count == self.items.count-1) { frame.origin.x = (self.frame.size.width-frame.size.width)/2.0; self.moreButton.hidden = YES; self.visibleItems = self.items; self.invisibleItems = nil; [self.contentView mas_remakeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(@0); make.centerY.equalTo(@0); }]; } else { frame.origin.x = leftButtonWidth; // self.moreButton.frame = NSMakeRect(self.frame.size.width-moreButtonWidth, 0, // moreButtonWidth, self.frame.size.height); [self.moreButton mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.bottom.equalTo(@0); make.width.offset(moreButtonWidth); make.right.equalTo(self.mas_right).offset(0); }]; self.moreButton.hidden = NO; self.visibleItems = [self.items subarrayWithRange:NSMakeRange(0, count+1)]; // self.invisibleItems = [self.items subarrayWithRange:NSMakeRange(count+1, self.items.count-count-1)]; [self.contentView mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.mas_left).offset(10); make.centerY.equalTo(@0); }]; } self.invisibleItems = @[].mutableCopy; [self.items enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { KMToolBoxItem *item = (KMToolBoxItem *)obj; if (CGRectGetMaxX(item.frame) <= self.frame.size.width-moreButtonWidth-leftButtonWidth) { item.hidden = NO; }else { item.hidden = YES; [self.invisibleItems addObject:item]; } }]; } #pragma mark - Public Methods - (void)reloadData { NSArray *leftitemIdentifiers = nil; if ([self.delegate respondsToSelector:@selector(toolbarLeftDefaultItemIdentifiers:)]) { leftitemIdentifiers = [self.delegate toolbarLeftDefaultItemIdentifiers:self]; } if (leftitemIdentifiers.count >0) { [self updateMainView]; }else { [self updateView]; } [self resizeSubviewsWithOldSize:self.frame.size]; } - (KMToolBoxItem *)itemForItemIdentifier:(NSString *)itemIdentifier { for (KMToolBoxItem *item in self.items) { if ([item.itemIdentifier isEqualToString:itemIdentifier]) { return item; } } return nil; } @end