-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathAppController.m
237 lines (186 loc) · 8.04 KB
/
AppController.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
//
// AppController.m
// MGScopeBar
//
// Copyright (c) 2008 Matt Gemmell
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#import "AppController.h"
#import "MGScopeBar.h"
// Keys for our sample data.
#define GROUP_LABEL @"Label" // string
#define GROUP_SEPARATOR @"HasSeparator" // BOOL as NSNumber
#define GROUP_SELECTION_MODE @"SelectionMode" // MGScopeBarGroupSelectionMode (int) as NSNumber
#define GROUP_ITEMS @"Items" // array of dictionaries, each containing the following keys:
#define ITEM_IDENTIFIER @"Identifier" // string
#define ITEM_NAME @"Name" // string
@implementation AppController
#pragma mark Setup and teardown
- (void)awakeFromNib
{
// In this method we basically just set up some sample data for the scope bar,
// so that we can respond to the MGScopeBarDelegate methods easily.
self.groups = [NSMutableArray arrayWithCapacity:0];
scopeBar.delegate = self;
// Add first group of items.
NSArray *items = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
@"HereItem", ITEM_IDENTIFIER,
@"Here", ITEM_NAME,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
@"ThereItem", ITEM_IDENTIFIER,
@"There", ITEM_NAME,
nil],
nil];
[self.groups addObject:[NSDictionary dictionaryWithObjectsAndKeys:
@"Search:", GROUP_LABEL,
[NSNumber numberWithBool:NO], GROUP_SEPARATOR,
[NSNumber numberWithInt:MGRadioSelectionMode], GROUP_SELECTION_MODE, // single selection group.
items, GROUP_ITEMS,
nil]];
// Add second group of items.
items = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
@"ContentsItem", ITEM_IDENTIFIER,
@"Contents", ITEM_NAME,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
@"FileNamesItem", ITEM_IDENTIFIER,
@"File Names", ITEM_NAME,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
@"MetadataItem", ITEM_IDENTIFIER,
@"Metadata", ITEM_NAME,
nil],
nil];
[self.groups addObject:[NSDictionary dictionaryWithObjectsAndKeys:
// deliberately not specifying a label
[NSNumber numberWithBool:YES], GROUP_SEPARATOR,
[NSNumber numberWithInt:MGMultipleSelectionMode], GROUP_SELECTION_MODE, // multiple selection group.
items, GROUP_ITEMS,
nil]];
// Add third group of items.
items = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
@"AllFilesItem", ITEM_IDENTIFIER,
@"All Files", ITEM_NAME,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
@"ImagesOnlyItem", ITEM_IDENTIFIER,
@"Images Only", ITEM_NAME,
nil],
nil];
[self.groups addObject:[NSDictionary dictionaryWithObjectsAndKeys:
@"Kind:", GROUP_LABEL,
[NSNumber numberWithBool:YES], GROUP_SEPARATOR,
[NSNumber numberWithInt:MGRadioSelectionMode], GROUP_SELECTION_MODE, // single selection group.
items, GROUP_ITEMS,
nil]];
// Tell the scope bar to ask us for data (since we're the scope-bar's delegate).
[scopeBar reloadData];
// Since our first group is a radio-mode group, the scope bar will automatically select its first item.
// The scope bar will take care of deselecting other items when you select a new item in a radio-mode group.
// We'll also select the first item in our second group, which is a multiple-selection group.
// You can (and must) use this method to programmatically select/deselect items in the bar.
[scopeBar setSelected:YES forItem:@"ContentsItem" inGroup:1]; // remember that group-numbers are zero-based.
// Clear out the label field below the scope bar.
[labelField setStringValue:@""];
}
- (void)dealloc
{
self.groups = nil;
[super dealloc];
}
#pragma mark MGScopeBarDelegate methods
- (int)numberOfGroupsInScopeBar:(MGScopeBar *)theScopeBar
{
return [self.groups count];
}
- (NSArray *)scopeBar:(MGScopeBar *)theScopeBar itemIdentifiersForGroup:(int)groupNumber
{
return [[self.groups objectAtIndex:groupNumber] valueForKeyPath:[NSString stringWithFormat:@"%@.%@", GROUP_ITEMS, ITEM_IDENTIFIER]];
}
- (NSString *)scopeBar:(MGScopeBar *)theScopeBar labelForGroup:(int)groupNumber
{
return [[self.groups objectAtIndex:groupNumber] objectForKey:GROUP_LABEL]; // might be nil, which is fine (nil means no label).
}
- (NSString *)scopeBar:(MGScopeBar *)theScopeBar titleOfItem:(NSString *)identifier inGroup:(int)groupNumber
{
NSArray *items = [[self.groups objectAtIndex:groupNumber] objectForKey:GROUP_ITEMS];
if (items) {
// We'll iterate here, since this is just a demo. This avoids having to keep an NSDictionary of identifiers
// for each group as well as an array for ordering. In a more realistic scenario, you'd probably want to be
// able to look-up an item by its identifier in constant time.
for (NSDictionary *item in items) {
if ([[item objectForKey:ITEM_IDENTIFIER] isEqualToString:identifier]) {
return [item objectForKey:ITEM_NAME];
break;
}
}
}
return nil;
}
- (MGScopeBarGroupSelectionMode)scopeBar:(MGScopeBar *)theScopeBar selectionModeForGroup:(int)groupNumber
{
return [[[self.groups objectAtIndex:groupNumber] objectForKey:GROUP_SELECTION_MODE] intValue];
}
- (BOOL)scopeBar:(MGScopeBar *)theScopeBar showSeparatorBeforeGroup:(int)groupNumber
{
// Optional method. If not implemented, all groups except the first will have a separator before them.
return [[[self.groups objectAtIndex:groupNumber] objectForKey:GROUP_SEPARATOR] boolValue];
}
- (NSImage *)scopeBar:(MGScopeBar *)scopeBar imageForItem:(NSString *)identifier inGroup:(int)groupNumber
{
// Optional method. If not implemented (or if you return nil), items will not have an image.
if (groupNumber == 0) {
return [NSImage imageNamed:@"NSComputer"];
} else if (groupNumber == 2) {
if ([identifier isEqualToString:@"AllFilesItem"]) {
return [NSImage imageNamed:@"NSGenericDocument"];
} else if ([identifier isEqualToString:@"ImagesOnlyItem"]) {
return [[NSWorkspace sharedWorkspace] iconForFileType:@"png"];
}
}
return nil;
}
- (NSView *)accessoryViewForScopeBar:(MGScopeBar *)scopeBar
{
// Optional method. If not implemented (or if you return nil), the scope-bar will not have an accessory view.
return accessoryView;
}
- (void)scopeBar:(MGScopeBar *)theScopeBar selectedStateChanged:(BOOL)selected
forItem:(NSString *)identifier inGroup:(int)groupNumber
{
// Display some text showing what just happened.
NSString *displayString = [NSString stringWithFormat:@"\"%@\" %@ in group %d.",
[self scopeBar:theScopeBar titleOfItem:identifier inGroup:groupNumber],
(selected) ? @"selected" : @"deselected",
groupNumber];
[labelField setStringValue:displayString];
//NSLog(@"%@", displayString);
}
#pragma mark Accessors and properties
@synthesize groups;
@end