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

Last change on this file since 600 was 600, checked in by Nicholas Riley, 9 years ago

Prototypes to pacify GCC.

File size: 6.1 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@interface NJRHotKeyField (Private)
24- (void)clearStatus;
25@end
26
27@implementation NJRHotKeyField
28
29+ (void)initialize;
30{
31    NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
32    [paraStyle setAlignment: NSLeftTextAlignment];
33    leftAlignStyle = [paraStyle copy];
34    [paraStyle setAlignment: NSCenterTextAlignment];
35    centerAlignStyle = [paraStyle copy];
36    [paraStyle release];
37
38    statusAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
39        [NSFont systemFontOfSize: [NSFont labelFontSize]], NSFontAttributeName,
40        centerAlignStyle, NSParagraphStyleAttributeName, nil];
41}
42
43- (void)_setUp;
44{
45    [self setAllowsEditingTextAttributes: YES];
46    [self setImportsGraphics: NO];
47    [self cell]->isa = [NJRHotKeyFieldCell class];
48}
49
50#pragma mark initialize-release
51
52- (id)initWithCoder:(NSCoder *)coder;
53{
54    if ( (self = [super initWithCoder: coder]) != nil) {
55        [self _setUp];
56    }
57    return self;
58}
59
60- (id)initWithFrame:(NSRect)frameRect;
61{
62    if ( (self = [super initWithFrame: frameRect]) != nil) {
63        [self _setUp];
64    }
65    return self;
66}
67
68- (void)dealloc;
69{
70    [hotKey release];
71    [super dealloc];
72}
73
74#pragma mark interface updating
75
76- (void)showStatus:(NSString *)error;
77{
78    [self setAttributedStringValue:
79        [[NSAttributedString alloc] initWithString: [NSString stringWithFormat: @"(%@)", error]
80                                        attributes: statusAttributes]];
81    [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(clearStatus) object: nil];
82    [self performSelector: @selector(clearStatus) withObject: nil afterDelay: 0.5];
83    [[self currentEditor] setSelectedRange: zeroRange];
84}
85
86- (void)previewKeyEquivalentAttributedString:(NSAttributedString *)equivString;
87{
88    NSMutableAttributedString *previewString = [equivString mutableCopy];
89    [previewString addAttribute: NSParagraphStyleAttributeName value: leftAlignStyle range: NSMakeRange(0, [previewString length])];
90    [self setAttributedStringValue: previewString];
91    [[self currentEditor] setSelectedRange: zeroRange];
92    [previewString release];
93}
94
95- (void)showKeyEquivalentAttributedStringFinalized:(BOOL)finalized;
96{
97    if ([hotKey characters] == nil) {
98        [self showStatus: @"none assigned"];
99        return;
100    }
101    NSMutableAttributedString *equivString = [[[hotKey characters] keyEquivalentAttributedStringWithModifierFlags: [hotKey modifierFlags]] mutableCopy];
102    [equivString addAttribute: NSParagraphStyleAttributeName
103                        value: (finalized ? centerAlignStyle : leftAlignStyle)
104                        range: NSMakeRange(0, [equivString length])];
105    [self setAttributedStringValue: equivString];
106    [[self currentEditor] setSelectedRange: zeroRange];
107    [equivString release];
108}
109
110- (void)clearStatus;
111{
112    if ([[[self attributedStringValue] attributesAtIndex: 0 effectiveRange: NULL] isEqualToDictionary: statusAttributes]) {
113        [self showKeyEquivalentAttributedStringFinalized: ([[NSApp currentEvent] modifierFlags] & capturedModifierMask) == 0];
114    }
115}
116
117- (void)textDidEndEditing:(NSNotification *)notification;
118{
119    [self showKeyEquivalentAttributedStringFinalized: YES];
120    [super textDidEndEditing: notification];
121}
122
123#pragma mark event handling
124
125- (void)keyUp:(NSEvent *)theEvent;
126{
127    NSString *characters = [theEvent charactersIgnoringModifiers];
128    int length = [characters length];
129    if (length > 1) {
130        [self showStatus: @"please press only one non-modifier key"];
131        return;
132    }
133    if (length == 1) {
134        unsigned modifierFlags = ([theEvent modifierFlags] & capturedModifierMask);
135        id delegate = [self delegate];
136        NSString *message = nil;
137        unichar character = [characters characterAtIndex: 0];
138        if (character == NSTabCharacter || character == NSBackTabCharacter)
139            return;
140        if (delegate != nil && ![delegate hotKeyField: self shouldAcceptCharacter: character modifierFlags: modifierFlags rejectionMessage: &message]) {
141            [self showStatus: message != nil ? message : @"key is unavailable for use"];
142        } else {
143            [self setHotKey: [NJRHotKey hotKeyWithCharacters: characters modifierFlags: modifierFlags keyCode: [theEvent keyCode]]];
144            [NSApp sendAction: [self action] to: [self target] from: self];
145            [self showKeyEquivalentAttributedStringFinalized: ([theEvent modifierFlags] & capturedModifierMask) == 0];
146        }
147    }
148}
149
150- (BOOL)performKeyEquivalent:(NSEvent *)theEvent;
151{
152    if ([[self window] firstResponder] == self)
153        [self keyUp: theEvent];
154    return [super performKeyEquivalent: theEvent];
155}
156
157- (void)flagsChanged:(NSEvent *)theEvent;
158{
159    unsigned modifierFlags = [theEvent modifierFlags];
160
161    if ((modifierFlags & capturedModifierMask) == 0) {
162        [self showKeyEquivalentAttributedStringFinalized: YES];
163    } else {
164        [self previewKeyEquivalentAttributedString:
165            [@"" keyEquivalentAttributedStringWithModifierFlags: modifierFlags]];
166    }
167}
168
169#pragma mark acccessing
170
171- (NJRHotKey *)hotKey;
172{
173    return hotKey;
174}
175
176- (void)setHotKey:(NJRHotKey *)aKey;
177{
178    if (aKey != hotKey) {
179        [hotKey release];
180        hotKey = [aKey retain];
181        [self showKeyEquivalentAttributedStringFinalized: ([[NSApp currentEvent] modifierFlags] & capturedModifierMask) == 0];
182    }
183}
184
185#pragma mark actions
186
187- (IBAction)clear:(id)sender;
188{
189    [self setHotKey: nil];
190    [NSApp sendAction: [self action] to: [self target] from: self];
191    [self showKeyEquivalentAttributedStringFinalized: YES];
192}
193
194@end
Note: See TracBrowser for help on using the repository browser.