Permalink
Browse files

Add the possibility to add a accessibility menu

  • Loading branch information...
1 parent ec9eafc commit 9562670583c0ab4c338bb7a88ea5ee34a203a991 @gcamp committed Jun 16, 2011
View
@@ -15,7 +15,10 @@
@property (nonatomic, assign) IBOutlet id<GCJumpBarDelegate> delegate;
@property (nonatomic, retain) IBOutlet NSMenu* menu;
+@property (nonatomic, retain) IBOutlet NSMenu* accessoryMenu;
+
@property (nonatomic, retain) NSIndexPath* selectedIndexPath;
+@property (nonatomic, assign) NSUInteger accessoryMenuSelectedIndex;
//Change automatically the font in the menu to be the same as the Jump Bar and resize the image to 16x16
@property (nonatomic, assign) BOOL changeFontAndImageInMenu;
@@ -29,5 +32,6 @@
@optional
- (void) jumpBar:(GCJumpBar*) jumpBar didSelectItemAtIndexPath:(NSIndexPath*) indexPath;
+- (void) jumpBar:(GCJumpBar *)jumpBar didSelectAccessoryMenuItemAtIndex:(NSUInteger) index;
@end
View
@@ -14,6 +14,8 @@
const CGFloat GCJumpBarNormalHeight = 23.0;
const CGFloat GCJumpBarNormalImageSize = 16.0;
+const NSInteger GCJumpBarAccessoryMenuLabelTag = -1;
+
@interface GCJumpBar () <GCJumpBarLabelDelegate>
@property (nonatomic, assign, getter = isUnderIdealWidth) BOOL underIdealWidth;
@@ -32,9 +34,11 @@ - (void) changeFontAndImageInMenu:(NSMenu*) subMenu;
@implementation GCJumpBar
@synthesize underIdealWidth;
+
@synthesize delegate;
-@synthesize menu;
-@synthesize selectedIndexPath;
+@synthesize menu, accessoryMenu;
+
+@synthesize selectedIndexPath, accessoryMenuSelectedIndex;
@synthesize changeFontAndImageInMenu;
- (id)initWithCoder:(NSCoder *)aDecoder {
@@ -62,6 +66,7 @@ - (id) initWithFrame:(NSRect)frameRect menu:(NSMenu*) aMenu {
if (self) {
self.menu = aMenu;
self.changeFontAndImageInMenu = YES;
+ self.accessoryMenuSelectedIndex = 0;
}
return self;
@@ -85,6 +90,17 @@ - (void)setMenu:(NSMenu *)newMenu {
}
}
+- (void)setAccessoryMenu:(NSMenu *)newAccessoryMenu {
+ if (newAccessoryMenu != accessoryMenu) {
+ [accessoryMenu release];
+ accessoryMenu = [newAccessoryMenu retain];
+
+ if (self.changeFontAndImageInMenu) [self changeFontAndImageInMenu:self.accessoryMenu];
+
+ [self performLayout];
+ }
+}
+
- (void)setSelectedIndexPath:(NSIndexPath *)newSelectedIndexPath {
if (newSelectedIndexPath != selectedIndexPath) {
[selectedIndexPath release];
@@ -98,6 +114,18 @@ - (void)setSelectedIndexPath:(NSIndexPath *)newSelectedIndexPath {
}
}
+- (void)setAccessoryMenuSelectedIndex:(NSUInteger)newAccessoryMenuSelectedIndex {
+ if (accessoryMenuSelectedIndex != newAccessoryMenuSelectedIndex) {
+ accessoryMenuSelectedIndex = newAccessoryMenuSelectedIndex;
+
+ [self performLayout];
+
+ if ([self.delegate respondsToSelector:@selector(jumpBar:didSelectAccessoryMenuItemAtIndex:)]) {
+ [self.delegate jumpBar:self didSelectAccessoryMenuItemAtIndex:self.accessoryMenuSelectedIndex];
+ }
+ }
+}
+
- (void)setEnabled:(BOOL)flag {
[super setEnabled:flag];
@@ -121,9 +149,14 @@ - (void)setBounds:(NSRect)aRect {
#pragma mark - Layout
- (void) performLayoutIfNeededWithNewSize:(CGSize) size {
- GCJumpBarLabel* lastLabel = [self viewWithTag:self.selectedIndexPath.length];
- if (size.width < (lastLabel.frame.size.width + lastLabel.frame.origin.x) || self.underIdealWidth) {
- [self performLayout];
+ if (self.accessoryMenu != nil || self.underIdealWidth) [self performLayout];
+ else {
+ GCJumpBarLabel* lastLabel = [self viewWithTag:self.selectedIndexPath.length];
+ CGFloat endFloat = lastLabel.frame.size.width + lastLabel.frame.origin.x;
+
+ if (size.width < endFloat) {
+ [self performLayout];
+ }
}
}
@@ -156,16 +189,37 @@ - (void)placeLabelAndSetValue {
baseX += frame.size.width;
label.frame = frame;
}
+
+ if (self.accessoryMenu != nil) {
+ GCJumpBarLabel* accessoryLabel = [self labelAtLevel:GCJumpBarAccessoryMenuLabelTag];
+
+ NSMenuItem* item = [self.accessoryMenu itemAtIndex:self.accessoryMenuSelectedIndex];
+ accessoryLabel.image = item.image;
+ accessoryLabel.text = item.title;
+ accessoryLabel.indexInLevel = self.accessoryMenuSelectedIndex;
+ [accessoryLabel sizeToFit];
+
+ NSRect frame = [accessoryLabel frame];
+ frame.origin.x = self.frame.size.width - accessoryLabel.frame.size.width;
+ accessoryLabel.frame = frame;
+ }
}
- (void)lookForOverflowWidth {
GCJumpBarLabel* lastLabel = [self viewWithTag:self.selectedIndexPath.length];
- if (self.frame.size.width < (lastLabel.frame.size.width + lastLabel.frame.origin.x)) {
+ CGFloat endFloat = lastLabel.frame.size.width + lastLabel.frame.origin.x;
+
+ if (self.accessoryMenu != nil) {
+ endFloat += [[self viewWithTag:GCJumpBarAccessoryMenuLabelTag] frame].size.width;
+ }
+
+ if (self.frame.size.width < endFloat) {
self.underIdealWidth = YES;
//Set new width for the overflow
- CGFloat overMargin = lastLabel.frame.size.width + lastLabel.frame.origin.x - self.frame.size.width;
- for (NSUInteger position = 0; position < self.selectedIndexPath.length ; position ++) {
+ CGFloat overMargin = endFloat - self.frame.size.width;
+ for (NSUInteger position = 0; position < self.selectedIndexPath.length + (self.accessoryMenu != nil); position ++) {
+ if (position == self.selectedIndexPath.length) position = GCJumpBarAccessoryMenuLabelTag - 1;
GCJumpBarLabel* label = [self labelAtLevel:position + 1];
if ((overMargin + label.minimumWidth - label.frame.size.width) < 0) {
CGRect frame = label.frame;
@@ -192,6 +246,14 @@ - (void)lookForOverflowWidth {
baseX += frame.size.width;
label.frame = frame;
}
+
+ if (self.accessoryMenu != nil) {
+ GCJumpBarLabel* accessoryLabel = [self labelAtLevel:GCJumpBarAccessoryMenuLabelTag];
+
+ NSRect frame = [accessoryLabel frame];
+ frame.origin.x = self.frame.size.width - accessoryLabel.frame.size.width;
+ accessoryLabel.frame = frame;
+ }
}
}
@@ -203,6 +265,8 @@ - (void)removeUnusedLabels {
[viewToRemove removeFromSuperview];
position ++;
}
+
+ if (self.accessoryMenu == nil) [[self viewWithTag:GCJumpBarAccessoryMenuLabelTag] removeFromSuperview];
}
#pragma mark - Drawing
@@ -305,14 +369,20 @@ - (NSMenuItem *)menuItemAtIndexPath:(NSIndexPath *)indexPath {
#pragma mark - GCJumpBarLabelDelegate
- (NSMenu *)menuToPresentWhenClickedForJumpBarLabel:(GCJumpBarLabel *)label {
- NSIndexPath* subIndexPath = [self.selectedIndexPath subIndexPathToPosition:label.level];
-
- return [[self.menu itemAtIndexPath:subIndexPath] menu];
+ if (label.tag == GCJumpBarAccessoryMenuLabelTag) return self.accessoryMenu;
+ else {
+ NSIndexPath* subIndexPath = [self.selectedIndexPath subIndexPathToPosition:label.level];
+
+ return [[self.menu itemAtIndexPath:subIndexPath] menu];
+ }
}
- (void)jumpBarLabel:(GCJumpBarLabel *)label didReceivedClickOnItemAtIndexPath:(NSIndexPath *)indexPath {
- NSIndexPath* subIndexPath = [self.selectedIndexPath subIndexPathToPosition:label.level - 1];
- self.selectedIndexPath = [subIndexPath indexPathByAddingIndexPath:indexPath];
+ if (label.tag == GCJumpBarAccessoryMenuLabelTag) self.accessoryMenuSelectedIndex = [indexPath indexAtPosition:0];
+ else {
+ NSIndexPath* subIndexPath = [self.selectedIndexPath subIndexPathToPosition:label.level - 1];
+ self.selectedIndexPath = [subIndexPath indexPathByAddingIndexPath:indexPath];
+ }
}
@end
View
@@ -11,6 +11,8 @@
const CGFloat GCJumpBarLabelMargin = 5.0;
+const NSInteger GCJumpBarLabelAccessoryMenuLabelTag = -1;
+
@interface GCJumpBarLabel ()
@property (nonatomic, readonly) NSDictionary* attributes;
@@ -81,7 +83,10 @@ - (void)mouseDown:(NSEvent *)theEvent {
NSMenu* menu = [self.delegate menuToPresentWhenClickedForJumpBarLabel:self];
[self setPropretyOnMenu:menu deep:0];
- [menu popUpMenuPositioningItem:[menu itemAtIndex:self.indexInLevel] atLocation:NSMakePoint(-16 , self.frame.size.height - 4) inView:self];
+ CGFloat xPoint = (self.tag == GCJumpBarLabelAccessoryMenuLabelTag ? - 9 : - 16);
+
+ [menu popUpMenuPositioningItem:[menu itemAtIndex:self.indexInLevel]
+ atLocation:NSMakePoint(xPoint , self.frame.size.height - 4) inView:self];
}
}
@@ -101,7 +106,15 @@ - (void) menuClicked:(id) sender {
#pragma mark - Dawing
- (void)drawRect:(NSRect)dirtyRect {
- CGFloat baseLeft = GCJumpBarLabelMargin;
+ CGFloat baseLeft = 0;
+
+ if (self.tag == GCJumpBarLabelAccessoryMenuLabelTag) {
+ NSImage* separatorImage = [NSImage imageNamed:@"GCJumpBarAccessorySeparator.png"];
+ [separatorImage drawAtPoint:NSMakePoint(baseLeft, self.frame.size.height / 2 - separatorImage.size.height / 2)
+ fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
+ baseLeft += separatorImage.size.width + GCJumpBarLabelMargin;
+ }
+ else baseLeft = GCJumpBarLabelMargin;
if (self.image != nil) {
[self.image drawAtPoint:NSMakePoint(baseLeft, floorf(self.frame.size.height / 2 - self.image.size.height / 2))
@@ -113,17 +126,18 @@ - (void)drawRect:(NSRect)dirtyRect {
if (self.text != nil) {
NSSize textSize = [self.text sizeWithAttributes:self.attributes];
- CGFloat width = self.frame.size.width - baseLeft - GCJumpBarLabelMargin - (!self.lastLabel * 7);
+ CGFloat width = self.frame.size.width - baseLeft - GCJumpBarLabelMargin;
+ if (!self.lastLabel && self.tag != GCJumpBarLabelAccessoryMenuLabelTag) width -= 7;
+
if (width > 0) {
[self.text drawInRect:CGRectMake(baseLeft, self.frame.size.height / 2 - textSize.height / 2
, width, textSize.height)
withAttributes:self.attributes];
baseLeft += width + GCJumpBarLabelMargin;
}
- //else if (self.image != nil) baseLeft += GCJumpBarLabelMargin;
}
- if (!self.lastLabel) {
+ if (!self.lastLabel && self.tag != GCJumpBarLabelAccessoryMenuLabelTag) {
NSImage* separatorImage = [NSImage imageNamed:@"GCJumpBarSeparator.png"];
[separatorImage drawAtPoint:NSMakePoint(baseLeft, self.frame.size.height / 2 - separatorImage.size.height / 2)
fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -17,6 +17,7 @@
B03A406E138D6F3A004677BE /* GCJumpBar.m in Sources */ = {isa = PBXBuildFile; fileRef = B03A4067138D6F3A004677BE /* GCJumpBar.m */; };
B03A406F138D6F3A004677BE /* GCJumpBarLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = B03A4069138D6F3A004677BE /* GCJumpBarLabel.m */; };
B03A4070138D6F3A004677BE /* GCJumpBarSeparator.png in Resources */ = {isa = PBXBuildFile; fileRef = B03A406B138D6F3A004677BE /* GCJumpBarSeparator.png */; };
+ B04247D413A9A99C005FF30D /* GCJumpBarAccessorySeparator.png in Resources */ = {isa = PBXBuildFile; fileRef = B04247D313A9A99B005FF30D /* GCJumpBarAccessorySeparator.png */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -41,6 +42,7 @@
B03A4068138D6F3A004677BE /* GCJumpBarLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCJumpBarLabel.h; sourceTree = "<group>"; };
B03A4069138D6F3A004677BE /* GCJumpBarLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCJumpBarLabel.m; sourceTree = "<group>"; };
B03A406B138D6F3A004677BE /* GCJumpBarSeparator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = GCJumpBarSeparator.png; sourceTree = "<group>"; };
+ B04247D313A9A99B005FF30D /* GCJumpBarAccessorySeparator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = GCJumpBarAccessorySeparator.png; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -141,6 +143,7 @@
B03A406A138D6F3A004677BE /* Image */ = {
isa = PBXGroup;
children = (
+ B04247D313A9A99B005FF30D /* GCJumpBarAccessorySeparator.png */,
B03A406B138D6F3A004677BE /* GCJumpBarSeparator.png */,
);
path = Image;
@@ -199,6 +202,7 @@
B03A403B138C295D004677BE /* MainMenu.xib in Resources */,
B03A4050138D5C34004677BE /* xcode.png in Resources */,
B03A4070138D6F3A004677BE /* GCJumpBarSeparator.png in Resources */,
+ B04247D413A9A99C005FF30D /* GCJumpBarAccessorySeparator.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Oops, something went wrong.

0 comments on commit 9562670

Please sign in to comment.