[142] | 1 | //
|
---|
| 2 | // ICeCoffEEKeyEquivalents.m
|
---|
| 3 | // ICeCoffEE APE
|
---|
| 4 | //
|
---|
| 5 | // Created by Nicholas Riley on Mon Jun 9 2003.
|
---|
| 6 | // Copyright (c) 2002 Nicholas Riley. All rights reserved.
|
---|
| 7 | //
|
---|
| 8 |
|
---|
| 9 | // Original implementations of these functions are in NSString-NJRExtensions
|
---|
| 10 | // and NSFont-NJRExtensions from Pester.
|
---|
| 11 |
|
---|
| 12 | #import <Carbon/Carbon.h>
|
---|
| 13 | #import <AppKit/AppKit.h>
|
---|
| 14 |
|
---|
| 15 | static NSFont *themeFont(ThemeFontID fontID) {
|
---|
| 16 | NSFont *themeFont = nil;
|
---|
| 17 | Str255 pstrFontName;
|
---|
| 18 | SInt16 fontSize = 0;
|
---|
| 19 | OSStatus status;
|
---|
| 20 | // can't simulate algorithmic styles in Cocoa in any case, so here's hoping nothing will be passed back - XXX guess this should at least accommodate the bold system font, but we don't need it
|
---|
| 21 | status = GetThemeFont(fontID, smSystemScript, pstrFontName, &fontSize, NULL);
|
---|
| 22 |
|
---|
| 23 | if (status == noErr) {
|
---|
| 24 | NSString *fontName = (NSString *)CFStringCreateWithPascalString(NULL, pstrFontName, CFStringGetSystemEncoding());
|
---|
| 25 | themeFont = [NSFont fontWithName: fontName size: fontSize];
|
---|
| 26 | [fontName release];
|
---|
| 27 | }
|
---|
| 28 | if (themeFont == nil) {
|
---|
| 29 | themeFont = [NSFont systemFontOfSize: fontSize == 0 ? [NSFont systemFontSize] : fontSize];
|
---|
| 30 | }
|
---|
| 31 | return themeFont;
|
---|
| 32 | }
|
---|
| 33 |
|
---|
| 34 | static NSString *stringWithCharacter(unichar character) {
|
---|
| 35 | return [NSString stringWithCharacters: &character length: 1];
|
---|
| 36 | }
|
---|
| 37 |
|
---|
| 38 | static unichar combiningHelpChar[] = {0x003F, 0x20DD};
|
---|
| 39 |
|
---|
| 40 | static NSFont *menuItemCmdKeyFont = nil;
|
---|
| 41 | static NSFont *menuItemFont = nil;
|
---|
| 42 | static NSParagraphStyle *keyEquivParaStyle;
|
---|
| 43 |
|
---|
| 44 | static inline void initialize() {
|
---|
| 45 | if (menuItemCmdKeyFont != nil) return;
|
---|
| 46 |
|
---|
| 47 | menuItemCmdKeyFont = [themeFont(kThemeMenuItemCmdKeyFont) retain];
|
---|
| 48 | menuItemFont = [themeFont(kThemeMenuItemFont) retain];
|
---|
| 49 |
|
---|
| 50 | NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
|
---|
| 51 | [paraStyle setTabStops: [NSArray arrayWithObjects:
|
---|
| 52 | [[[NSTextTab alloc] initWithType: NSRightTabStopType location: 30] autorelease],
|
---|
| 53 | [[[NSTextTab alloc] initWithType: NSLeftTabStopType location: 30.01] autorelease],
|
---|
| 54 | nil]];
|
---|
| 55 | [paraStyle setLineBreakMode: NSLineBreakByClipping];
|
---|
| 56 | keyEquivParaStyle = [paraStyle copy];
|
---|
| 57 | [paraStyle release];
|
---|
| 58 | }
|
---|
| 59 |
|
---|
| 60 | // set tabs here, for ICeCoffEE (not in Pester)
|
---|
| 61 | static NSAttributedString *attributedStringWithFont(NSString *self, NSFont *font) {
|
---|
| 62 | return [[[NSAttributedString alloc] initWithString: self attributes: [NSDictionary dictionaryWithObjectsAndKeys: font, NSFontAttributeName, keyEquivParaStyle, NSParagraphStyleAttributeName, nil]] autorelease];
|
---|
| 63 | }
|
---|
| 64 |
|
---|
| 65 | static NSString *keyEquivalentString(NSString *self) {
|
---|
| 66 | if ([self length] != 0) {
|
---|
| 67 | const char *str = [self UTF8String];
|
---|
| 68 | unichar keyChar;
|
---|
| 69 | if (str[1] != '\0') {
|
---|
| 70 | keyChar = [self characterAtIndex: 0];
|
---|
| 71 | switch (keyChar) {
|
---|
| 72 | case NSUpArrowFunctionKey: keyChar = 0x21E1; break;
|
---|
| 73 | case NSDownArrowFunctionKey: keyChar = 0x21E3; break;
|
---|
| 74 | case NSLeftArrowFunctionKey: keyChar = 0x21E0; break;
|
---|
| 75 | case NSRightArrowFunctionKey: keyChar = 0x21E2; break;
|
---|
| 76 | case NSInsertFunctionKey:
|
---|
| 77 | return [NSString stringWithCharacters: combiningHelpChar length: 2];
|
---|
| 78 | case NSDeleteFunctionKey: keyChar = 0x2326; break;
|
---|
| 79 | case NSHomeFunctionKey: keyChar = 0x2196; break;
|
---|
| 80 | case NSEndFunctionKey: keyChar = 0x2198; break;
|
---|
| 81 | case NSPageUpFunctionKey: keyChar = 0x21DE; break;
|
---|
| 82 | case NSPageDownFunctionKey: keyChar = 0x21DF; break;
|
---|
| 83 | case NSClearLineFunctionKey: keyChar = 0x2327; break;
|
---|
| 84 | default:
|
---|
| 85 | if (keyChar >= NSF1FunctionKey && keyChar <= NSF35FunctionKey) {
|
---|
| 86 | return [NSString stringWithFormat: @"F%u", keyChar - NSF1FunctionKey + 1];
|
---|
| 87 | }
|
---|
| 88 | return [NSString stringWithFormat: @"[unknown %lX]", keyChar];
|
---|
| 89 | }
|
---|
| 90 | } else if (str[0] >= 'A' && str[0] <= 'Z') {
|
---|
| 91 | return self;
|
---|
| 92 | } else if (str[0] >= 'a' && str[0] <= 'z') return [self uppercaseString];
|
---|
| 93 | else switch (str[0]) {
|
---|
| 94 | case '\t': keyChar = 0x21e5; break;
|
---|
| 95 | case '\r': keyChar = 0x21a9; break;
|
---|
| 96 | case '\e': keyChar = 0x238b; break;
|
---|
| 97 | case ' ': keyChar = 0x2423; break;
|
---|
| 98 | case 0x7f: keyChar = 0x232b; break; // delete
|
---|
| 99 | case 0x03: keyChar = 0x2324; break; // enter
|
---|
| 100 | case 0x19: keyChar = 0x21e4; break; // backtab
|
---|
| 101 | case 0: return @"";
|
---|
| 102 | // case '': keyChar = 0x; break;
|
---|
| 103 | default: return self; // return [NSString stringWithFormat: @"[huh? %x]", (int)str[0]];
|
---|
| 104 | }
|
---|
| 105 | return stringWithCharacter(keyChar);
|
---|
| 106 | }
|
---|
| 107 | return self;
|
---|
| 108 | }
|
---|
| 109 |
|
---|
| 110 | NSAttributedString *ICCF_KeyEquivalentAttributedStringWithModifierFlags(NSString *self, unsigned int modifierFlags) {
|
---|
| 111 | initialize();
|
---|
| 112 | NSString *keyEquivalentStringNoMask = keyEquivalentString(self);
|
---|
| 113 | // use tabs here, for ICeCoffEE (not in Pester, at least without better subclassing)
|
---|
| 114 | NSAttributedString *keyEquivalentAttributedString =
|
---|
| 115 | attributedStringWithFont(
|
---|
| 116 | [NSString stringWithFormat: @"\t%@%@%@%@\t%@",
|
---|
| 117 | (modifierFlags & NSControlKeyMask) ? stringWithCharacter(kControlUnicode) : @"",
|
---|
| 118 | (modifierFlags & NSAlternateKeyMask) ? stringWithCharacter(kOptionUnicode) : @"",
|
---|
| 119 | (modifierFlags & NSShiftKeyMask) ? stringWithCharacter(kShiftUnicode) : @"",
|
---|
| 120 | (modifierFlags & NSCommandKeyMask) ? stringWithCharacter(kCommandUnicode) : @"",
|
---|
| 121 | keyEquivalentStringNoMask], menuItemCmdKeyFont);
|
---|
| 122 | unsigned noMaskLength = [keyEquivalentStringNoMask length];
|
---|
| 123 | if (noMaskLength > 3 || // Fxx
|
---|
| 124 | (noMaskLength == 1 && [keyEquivalentStringNoMask characterAtIndex: 0] <= 0x7F)) {
|
---|
| 125 | NSMutableAttributedString *astr = [keyEquivalentAttributedString mutableCopy];
|
---|
| 126 | [astr setAttributes: [NSDictionary dictionaryWithObject: menuItemFont forKey: NSFontAttributeName] range: NSMakeRange([astr length] - noMaskLength, noMaskLength)];
|
---|
| 127 | keyEquivalentAttributedString = [[astr copy] autorelease];
|
---|
| 128 | [astr release];
|
---|
| 129 | }
|
---|
| 130 | return keyEquivalentAttributedString;
|
---|
| 131 | } |
---|