/
DZSelectableBox.m
175 lines (147 loc) · 3.87 KB
/
DZSelectableBox.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//
// DZSelectableBox.m
// SelectedBox
//
// Created by unixo <unixo@devzero.it> on 13/12/09.
// Copyright 2009 Ferruccio Vitale. All rights reserved.
//
#import "DZSelectableBox.h"
@implementation DZSelectableBox
@synthesize selectedBgColor;
@synthesize selectedBorderColor;
@synthesize radioGroup;
- (id) init
{
if ((self = [super init])) {
[self _setDefaultValues];
}
return self;
}
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
selectedBorderColor = nil;
selectedBgColor = nil;
[super dealloc];
}
- (void)awakeFromNib
{
[self _setDefaultValues];
}
- (BOOL)preservesContentDuringLiveResize
{
return NO;
}
- (void) _setDefaultValues
{
// By default, this box is not selected
selected = NO;
// Make border and background look like the box found in "iSync conflict"
[self setFillColor:[NSColor colorWithCalibratedWhite:0.965 alpha:1.000]];
[self setBorderColor:[NSColor colorWithCalibratedRed:0.819 green:0.773
blue:0.813 alpha:1.000]];
// Color of the inner border
self.selectedBorderColor = [NSColor colorWithCalibratedRed:0.192 green:0.417
blue:0.884 alpha:1.000];
// Color of the inner background
self.selectedBgColor = [NSColor colorWithCalibratedRed:0.769 green:0.847
blue:0.950 alpha:1.000];
// By default, this box is not part of any radio group
self.radioGroup = [NSNumber numberWithInt:-1];
_borderWidth = 10;
_radius = 4.0;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_update:)
name:DZSelectableBoxNotification
object:nil];
}
- (void) _update:(NSNotification *)aNotification
{
// If this notification was originated by this box or if this box is not
// part of any radio group, ignore it!
if (([aNotification object] == self) || ([self.radioGroup intValue] == -1))
return;
// Check if radio group contained in notification user info is equal to our
NSNumber *num = [[aNotification userInfo] valueForKey:@"radioGroup"];
if ([num intValue] != [self.radioGroup intValue])
return;
if (selected) {
selected = NO;
[self setNeedsDisplay:YES];
}
}
- (void) _notifyRadioGroup
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:self.radioGroup
forKey:@"radioGroup"];
[[NSNotificationCenter defaultCenter] postNotificationName:DZSelectableBoxNotification
object:self
userInfo:userInfo];
}
- (BOOL) selected
{
return selected;
}
- (void) setSelected:(BOOL)aValue
{
BOOL oldValue = selected;
selected = aValue;
if (oldValue != aValue) {
[self setNeedsDisplay:YES];
[self _notifyRadioGroup];
}
}
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
if (selected) {
NSTitlePosition titlePos;
NSRect bgRect = [self bounds];
if ((titlePos = [self titlePosition]) != NSNoTitle) {
NSRect titleRect = [self titleRect];
switch (titlePos) {
case NSAtTop:
bgRect.size.height -= titleRect.size.height - 2;
break;
case NSAboveTop:
bgRect.size.height -= titleRect.size.height - 4;
break;
case NSBelowTop:
bgRect.size.height -= titleRect.size.height - 3;
break;
case NSAtBottom:
bgRect.origin.y += 6;
bgRect.size.height -= 5;
break;
default:
break;
}
bgRect = NSInsetRect(bgRect, 8, 8);
} else {
bgRect = NSInsetRect(bgRect, 4, 4);
}
NSBezierPath *bgPath = [NSBezierPath bezierPathWithRoundedRect:bgRect
xRadius:_radius
yRadius:_radius];
[selectedBgColor set];
[bgPath fill];
[selectedBorderColor set];
[bgPath setLineWidth:2.0];
[bgPath stroke];
}
}
- (void) toggleState
{
if ([radioGroup intValue] >= 0) {
if (selected)
return;
}
selected = !selected;
[self setNeedsDisplay:YES];
[self _notifyRadioGroup];
}
- (void)mouseDown:(NSEvent *)theEvent
{
[self toggleState];
[super mouseDown:theEvent];
}
@end