mirror of
https://github.com/textmate/textmate.git
synced 2026-01-22 05:07:54 -05:00
Improve tab trigger rendering
This is using NSAttributedString’s NSTextTableBlocks: * Font is determined from current menu rather than hardcoded * Fixed: Invalid font size on bundle-item popup * Fixed: Both tab triggers and key equivalents can co exists on single menu item * No relayout calculations are needed after menu update (this is done automatically by NSLayoutManager when using NSTextTables) * Uses 10.5 compatible API
This commit is contained in:
committed by
Allan Odgaard
parent
15afc1398b
commit
7bd9f9817b
@@ -83,6 +83,109 @@ static void set_legacy_key_equivalent (MenuRef aMenu, UInt16 anIndex, std::strin
|
||||
SetMenuItemModifiers(aMenu, anIndex, modifiers);
|
||||
}
|
||||
|
||||
@interface MenuMutableAttributedString : NSMutableAttributedString
|
||||
{
|
||||
NSMutableAttributedString* contents;
|
||||
CGSize size;
|
||||
}
|
||||
- (void)appendTableCellWithString:(NSString*)string table:(NSTextTable*)table textAlignment:(NSTextAlignment)textAlignment verticalAlignment:(NSTextBlockVerticalAlignment)verticalAlignment font:(NSFont*)font row:(int)row column:(int)column;
|
||||
- (CGSize)size;
|
||||
@end
|
||||
|
||||
@implementation MenuMutableAttributedString
|
||||
|
||||
// Methods to override in subclass
|
||||
|
||||
- (id)init
|
||||
{
|
||||
return [self initWithAttributedString:nil];
|
||||
}
|
||||
|
||||
- (id)initWithAttributedString:(NSAttributedString*)attributedString
|
||||
{
|
||||
if(self = [super init])
|
||||
contents = attributedString ? [attributedString mutableCopy] : [[NSMutableAttributedString alloc] init];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString*)string
|
||||
{
|
||||
return [contents string];
|
||||
}
|
||||
|
||||
- (NSDictionary*)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRange*)range
|
||||
{
|
||||
return [contents attributesAtIndex:location effectiveRange:range];
|
||||
}
|
||||
|
||||
- (void)replaceCharactersInRange:(NSRange)range withString:(NSString*)string
|
||||
{
|
||||
[contents replaceCharactersInRange:range withString:string];
|
||||
}
|
||||
|
||||
- (void)setAttributes:(NSDictionary*)attributes range:(NSRange)range
|
||||
{
|
||||
[contents setAttributes:attributes range:range];
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
MenuMutableAttributedString* copy = [MenuMutableAttributedString allocWithZone:zone];
|
||||
copy->contents = [contents copyWithZone:zone];
|
||||
copy->size = size;
|
||||
return copy;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[contents release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// NOTE: AppKit additions produce invalid values here, provide our own implementation
|
||||
|
||||
- (NSRect)boundingRectWithSize:(NSSize)aSize options:(NSStringDrawingOptions)options
|
||||
{
|
||||
return NSMakeRect(0, 0, size.width, size.height);
|
||||
}
|
||||
|
||||
// Helper method for adding table cell into the attributed string
|
||||
|
||||
- (void)appendTableCellWithString:(NSString*)string table:(NSTextTable*)table textAlignment:(NSTextAlignment)textAlignment verticalAlignment:(NSTextBlockVerticalAlignment)verticalAlignment font:(NSFont*)font row:(int)row column:(int)column;
|
||||
{
|
||||
CGSize stringSize = [string sizeWithAttributes:[NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]];
|
||||
|
||||
NSTextTableBlock* block = [[[NSTextTableBlock alloc] initWithTable:table startingRow:row rowSpan:1 startingColumn:column columnSpan:1] autorelease];
|
||||
|
||||
if(column > 0)
|
||||
[block setContentWidth:stringSize.width type:NSTextBlockAbsoluteValueType];
|
||||
|
||||
block.verticalAlignment = verticalAlignment;
|
||||
|
||||
NSMutableParagraphStyle* paragraphStyle = [[[NSMutableParagraphStyle alloc] init] autorelease];
|
||||
[paragraphStyle setTextBlocks:[NSArray arrayWithObjects:block, nil]];
|
||||
[paragraphStyle setAlignment:textAlignment];
|
||||
|
||||
string = [string stringByAppendingString:@"\n"];
|
||||
|
||||
NSMutableAttributedString* cellString = [[[NSMutableAttributedString alloc] initWithString:string] autorelease];
|
||||
[cellString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [cellString length])];
|
||||
[cellString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [cellString length])];
|
||||
|
||||
size.width += stringSize.width;
|
||||
if(size.height < stringSize.height)
|
||||
size.height = stringSize.height;
|
||||
|
||||
[self appendAttributedString:cellString];
|
||||
}
|
||||
|
||||
- (CGSize)size
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSMenuItem (FileIcon)
|
||||
- (void)setIconForFile:(NSString*)path;
|
||||
{
|
||||
@@ -144,16 +247,16 @@ static void set_legacy_key_equivalent (MenuRef aMenu, UInt16 anIndex, std::strin
|
||||
if(aTabTrigger == NULL_STR)
|
||||
return;
|
||||
|
||||
if(MenuRef menu = _NSGetCarbonMenu([self menu]))
|
||||
{
|
||||
MenuItemIndex itemIndex = [[self menu] indexOfItem:self] + 1;
|
||||
MenuMutableAttributedString* attributedTitle = [[[MenuMutableAttributedString alloc] init] autorelease];
|
||||
NSTextTable* table = [[[NSTextTable alloc] init] autorelease];
|
||||
[table setNumberOfColumns:2];
|
||||
|
||||
ChangeMenuItemAttributes(menu, itemIndex, kMenuItemAttrCustomDraw, 0);
|
||||
std::string const& tabTrigger(aTabTrigger + "⇥");
|
||||
size_t len = tabTrigger.size();
|
||||
SetMenuItemProperty(menu, itemIndex, 'TxMt', 'TbLn', sizeof(size_t), &len);
|
||||
SetMenuItemProperty(menu, itemIndex, 'TxMt', 'TbTr', tabTrigger.size(), tabTrigger.data());
|
||||
}
|
||||
NSFont* font = self.menu.font ?: [NSFont menuFontOfSize:0];
|
||||
[attributedTitle appendTableCellWithString:self.title table:table textAlignment:NSLeftTextAlignment verticalAlignment:NSTextBlockMiddleAlignment font:font row:0 column:0];
|
||||
[attributedTitle appendTableCellWithString:[NSString stringWithCxxString:(" "+aTabTrigger+"\u21E5")] table:table textAlignment:NSRightTextAlignment
|
||||
verticalAlignment:font.pointSize >= 13 ? NSTextBlockBottomAlignment : NSTextBlockMiddleAlignment
|
||||
font:[NSFont menuBarFontOfSize:floor(font.pointSize * 0.85)] row:0 column:1];
|
||||
self.attributedTitle = attributedTitle;
|
||||
}
|
||||
|
||||
- (void)setModifiedState:(BOOL)flag
|
||||
|
||||
Reference in New Issue
Block a user