-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathSSYLabelledPopUp.m
executable file
·149 lines (113 loc) · 4.18 KB
/
SSYLabelledPopUp.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#import "SSYLabelledPopUp.h"
#import "NSView+Layout.h"
#import "NSPopUpButton+Populating.h"
#import "SSYAlert.h"
NSString* const constKeyLabelField = @"LabelField" ;
NSString* const constKeyPopUpButton = @"PopUpButton" ;
@implementation SSYLabelledPopUp
@synthesize labelField ;
@synthesize popUpButton ;
//- (void)setDisplayedKey:(NSString*)label {
// [[self labelField] setStringValue:label] ;
//}
- (void)setChoices:(NSArray*)choices {
[[self popUpButton] populateTitles:choices
target:self
action:@selector(doNothing:)] ;
}
- (IBAction)doNothing:(id)sender {
// Even if button does nothing, must still have
// a dummy target and action to be enabled.
}
- (NSInteger)selectedIndex {
return [[self popUpButton] selectedTag] ;
}
#define CONTROL_VERTICAL_SPACING 14.0
- (void)sizeHeightToFitAllowShrinking:(BOOL)allowShrinking {
[[self labelField] sizeHeightToFitAllowShrinking:allowShrinking] ;
[self setHeight:
[[self popUpButton] height]
+ CONTROL_VERTICAL_SPACING
+ [[self labelField] height]] ;
}
- (id)initWithLabel:(NSString*)label {
self = [super initWithFrame:NSZeroRect] ;
if (self != nil) {
CGFloat y ;
NSPopUpButton* button ;
button = [[NSPopUpButton alloc] initWithFrame:NSZeroRect
pullsDown:NO] ;
[button setHeight:22] ; // for NSPopUpButton with control size = small.
// Note: Setting the above to > 22 causes no change in actual size
[button setLeftEdge:0.0] ;
[button setBottom:0.0] ;
[self setPopUpButton:button] ;
[self addSubview:button] ;
y = [button height] ;
[button release] ;
NSTextField* textField ;
textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, [SSYAlert smallTextHeight])] ;
[textField setFont:[SSYAlert smallTextFont]] ;
[textField setBordered:NO] ;
[textField setEditable:NO] ;
[textField setDrawsBackground:NO] ;
[textField setStringValue:label] ;
y += 0 ; // No vertical spacing between label and popup
[textField setLeftEdge:0.0] ;
[textField setBottom:y] ;
[self setLabelField:textField] ;
[self addSubview:textField] ;
y += [textField height] ;
[textField release] ;
[self setAutoresizingMask:NSViewWidthSizable] ;
// Start out with self and subviews all at same width,
// then set to track future changes to self's width
[self setWidth:[textField width]] ;
[[self labelField] setAutoresizingMask:NSViewWidthSizable] ;
[[self popUpButton] setAutoresizingMask:NSViewWidthSizable] ;
[self setHeight:y] ;
// This looks weird. I suppose it makes sense, if there is only
// one field in the keyboard loop at this level??
[button setNextKeyView:button] ;
}
return self;
}
- (BOOL)becomeFirstResponder {
BOOL x = [[self window] makeFirstResponder:[self popUpButton]] ;
return x ;
}
- (void)setNextKeyView:(NSView*)view {
[[self popUpButton] setNextKeyView:view] ;
}
+ (SSYLabelledPopUp*)popUpControlWithLabel:(NSString*)label {
SSYLabelledPopUp* instance = [[SSYLabelledPopUp alloc] initWithLabel:label] ;
return [instance autorelease] ;
}
- (void) dealloc {
[labelField release] ;
[popUpButton release] ;
[super dealloc];
}
- (BOOL)acceptsFirstResponder {
return YES ;
}
#pragma mark * NSCoding Protocol Conformance
// See http://developer.apple.com/documentation/Cocoa/Conceptual/Archiving/Tasks/codingobjects.html
// Although NSResponder::NSControl subclasses can sometimes get away with not implementing these
// two methods, not so if the control is used in SSYAlert, because SSYAlert will encode it when
// adding to its configurations stack.
// @encode(type_spec) is a compiler directive that returns a character string that encodes
// the type structure of type_spec. It can be used as the first argument of can be used as
// the first argument of encodeValueOfObjCType:at:
- (void)encodeWithCoder:(NSCoder *)coder {
[super encodeWithCoder:coder] ;
[coder encodeObject:labelField forKey:constKeyLabelField] ;
[coder encodeObject:popUpButton forKey:constKeyPopUpButton] ;
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder] ;
labelField = [[coder decodeObjectForKey:constKeyLabelField] retain] ;
popUpButton = [[coder decodeObjectForKey:constKeyPopUpButton] retain] ;
return self ;
}
@end