source: trunk/Cocoa/Pester/Source/NJRHotKeyField.m @ 131

Last change on this file since 131 was 131, checked in by Nicholas Riley, 17 years ago

PSPreferencesController.[hm]: Added support for registering hot keys;
not the most elegant thing in the world, but much better than it was
in the prototype. Triggered by +readPreferences.

NJRHotKeyField.[hm]: Replaced model components (wow, was that ever
dumb) by NJRHotKey reference, eliminating cumbersome archiving model.
Added accessors for hot key.

NJRHotKeyManager.[hm]: Ported Quentin Carnicelli's HotKeyCenter? code
to use NJRHotKey, cleaned up, and removed reverse-engineered pre-10.2
support.

NJRHotKey.[hm]: New. Provides Cocoa-centric storage for
three-component hot keys, mapping from Cocoa to Carbon modifiers.

PSApplication.m: Reorganized. Added invocation of
+[PSPreferencesController readPreferences].

Fixes bug 29.

File size: 5.3 KB
Line 
1//
2//  NJRHotKeyField.m
3//  Pester
4//
5//  Created by Nicholas Riley on Sat Mar 29 2003.
6//  Copyright (c) 2003 Nicholas Riley. All rights reserved.
7//
8
9#import "NJRHotKeyField.h"
10#import "NJRHotKeyFieldCell.h"
11#import "NJRHotKey.h"
12#import "NSString-NJRExtensions.h"
13
14static const NSRange zeroRange = {0, 0};
15static const unsigned int capturedModifierMask = (NSShiftKeyMask |
16                                                  NSControlKeyMask |
17                                                  NSAlternateKeyMask |
18                                                  NSCommandKeyMask);
19
20static NSParagraphStyle *leftAlignStyle = nil, *centerAlignStyle = nil;
21static NSDictionary *statusAttributes = nil;
22
23@implementation NJRHotKeyField
24
25+ (void)initialize;
26{
27    NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
28    [paraStyle setAlignment: NSLeftTextAlignment];
29    leftAlignStyle = [paraStyle copy];
30    [paraStyle setAlignment: NSCenterTextAlignment];
31    centerAlignStyle = [paraStyle copy];
32    [paraStyle release];
33
34    statusAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
35        [NSFont systemFontOfSize: [NSFont labelFontSize]], NSFontAttributeName,
36        centerAlignStyle, NSParagraphStyleAttributeName, nil];
37}
38
39- (void)_setUp;
40{
41    [self setAllowsEditingTextAttributes: YES];
42    [self setImportsGraphics: NO];
43    [self cell]->isa = [NJRHotKeyFieldCell class];
44}
45
46#pragma mark initialize-release
47
48- (id)initWithCoder:(NSCoder *)coder;
49{
50    if ( (self = [super initWithCoder: coder]) != nil) {
51        [self _setUp];
52    }
53    return self;
54}
55
56- (id)initWithFrame:(NSRect)frameRect;
57{
58    if ( (self = [super initWithFrame: frameRect]) != nil) {
59        [self _setUp];
60    }
61    return self;
62}
63
64- (void)dealloc;
65{
66    [hotKey release];
67}
68
69#pragma mark interface updating
70
71// XXX still problems with command-A the first time
72
73- (void)previewKeyEquivalentAttributedString:(NSAttributedString *)equivString;
74{
75    NSMutableAttributedString *previewString = [equivString mutableCopy];
76    [previewString addAttribute: NSParagraphStyleAttributeName value: leftAlignStyle range: NSMakeRange(0, [previewString length])];
77    [self setAttributedStringValue: previewString];
78    [[self currentEditor] setSelectedRange: zeroRange];
79    [previewString release];
80}
81
82- (void)showStatus:(NSString *)error;
83{
84    [self setAttributedStringValue:
85        [[NSAttributedString alloc] initWithString: [NSString stringWithFormat: @"(%@)", error]
86                                        attributes: statusAttributes]];
87    [[self currentEditor] setSelectedRange: zeroRange];
88}
89
90- (void)showKeyEquivalentAttributedStringFinalized:(BOOL)finalized;
91{
92    if ([hotKey characters] == nil) {
93        [self showStatus: @"none assigned"];
94        return;
95    }
96    NSMutableAttributedString *equivString = [[[hotKey characters] keyEquivalentAttributedStringWithModifierFlags: [hotKey modifierFlags]] mutableCopy];
97    [equivString addAttribute: NSParagraphStyleAttributeName
98                        value: (finalized ? centerAlignStyle : leftAlignStyle)
99                        range: NSMakeRange(0, [equivString length])];
100    [self setAttributedStringValue: equivString];
101    [[self currentEditor] setSelectedRange: zeroRange];
102    [equivString release];
103}
104
105#pragma mark event handling
106
107- (void)keyUp:(NSEvent *)theEvent;
108{
109    NSString *characters = [theEvent charactersIgnoringModifiers];
110    int length = [characters length];
111    if (length > 1) {
112        [self showStatus: @"please press only one non-modifier key"];
113        return;
114    }
115    if (length == 1) {
116        unsigned modifierFlags = ([theEvent modifierFlags] & capturedModifierMask);
117        id delegate = [self delegate];
118        NSString *message = nil;
119        if (delegate != nil && ![delegate hotKeyField: self shouldAcceptCharacter: [characters characterAtIndex: 0] modifierFlags: modifierFlags rejectionMessage: &message]) {
120            [self showStatus: message != nil ? message : @"key is unavailable for use"];
121        } else {
122            [self setHotKey: [NJRHotKey hotKeyWithCharacters: characters modifierFlags: modifierFlags keyCode: [theEvent keyCode]]];
123            [NSApp sendAction: [self action] to: [self target] from: self];
124            [self showKeyEquivalentAttributedStringFinalized: ([theEvent modifierFlags] & capturedModifierMask) == 0];
125        }
126    }
127}
128
129- (BOOL)performKeyEquivalent:(NSEvent *)theEvent;
130{
131    [self keyUp: theEvent];
132    return [super performKeyEquivalent: theEvent];
133}
134
135- (void)flagsChanged:(NSEvent *)theEvent;
136{
137    unsigned modifierFlags = [theEvent modifierFlags];
138
139    if ((modifierFlags & capturedModifierMask) == 0) {
140        [self showKeyEquivalentAttributedStringFinalized: YES];
141    } else {
142        [self previewKeyEquivalentAttributedString:
143            [@"" keyEquivalentAttributedStringWithModifierFlags: modifierFlags]];
144    }
145}
146
147#pragma mark acccessing
148
149- (NJRHotKey *)hotKey;
150{
151    return hotKey;
152}
153
154- (void)setHotKey:(NJRHotKey *)aKey;
155{
156    if (aKey != hotKey) {
157        [hotKey release];
158        hotKey = [aKey retain];
159        [self showKeyEquivalentAttributedStringFinalized: ([[NSApp currentEvent] modifierFlags] & capturedModifierMask) == 0];
160    }
161}
162
163#pragma mark actions
164
165- (IBAction)clear:(id)sender;
166{
167    [self setHotKey: nil];
168    [NSApp sendAction: [self action] to: [self target] from: self];
169    [self showKeyEquivalentAttributedStringFinalized: YES];
170}
171
172@end
Note: See TracBrowser for help on using the repository browser.