X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=OSX%2FSaverListController.m;h=904f570a6af2afaf453cf4c960852b14aa4f85ff;hb=d5186197bc394e10a4402f7f6d23fbb14103bc50;hp=484cb1685449bdb50a625d1a7ccfe445c23e27eb;hpb=6f5482d73adb0165c0130bb47d852644ab0c4869;p=xscreensaver diff --git a/OSX/SaverListController.m b/OSX/SaverListController.m index 484cb168..904f570a 100644 --- a/OSX/SaverListController.m +++ b/OSX/SaverListController.m @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 2012 Jamie Zawinski +/* xscreensaver, Copyright (c) 2012-2014 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -36,6 +36,7 @@ { // Extract the version number and release date from the version string. // Here's an area where I kind of wish I had "Two Problems". + // I guess I could add custom key to the Info.plist for this. NSArray *a = [[NSString stringWithCString: screensaver_id encoding:NSASCIIStringEncoding] @@ -57,15 +58,16 @@ UIImage *img = [UIImage imageWithContentsOfFile: [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: - @"iSaverRunner29t.png"]]; - UIBarButtonItem *button = [[[UIBarButtonItem alloc] - initWithImage: img - style: UIBarButtonItemStylePlain - target: self - action: @selector(titleTapped:)] - autorelease]; - button.width = img.size.width; - self.navigationItem.rightBarButtonItem = button; + @"iSaverRunner57t.png"]]; + UIButton *button = [[UIButton alloc] init]; + [button setFrame: CGRectMake(0, 0, img.size.width/2, img.size.height/2)]; + [button setBackgroundImage:img forState:UIControlStateNormal]; + [button addTarget:self + action:@selector(titleTapped:) + forControlEvents:UIControlEventTouchUpInside]; + self.navigationItem.rightBarButtonItem = + [[UIBarButtonItem alloc] initWithCustomView: button]; + [button release]; // The title bar @@ -87,8 +89,8 @@ CGRect win = [self view].frame; if (win.size.width > 320) { // iPad - [label1 setTextAlignment: UITextAlignmentLeft]; - [label2 setTextAlignment: UITextAlignmentRight]; + [label1 setTextAlignment: NSTextAlignmentLeft]; + [label2 setTextAlignment: NSTextAlignmentRight]; label2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; r3.size.width = win.size.width; r1 = r3; @@ -98,8 +100,8 @@ } else { // iPhone r3.size.width = 320; // force it to be flush-left - [label1 setTextAlignment: UITextAlignmentLeft]; - [label2 setTextAlignment: UITextAlignmentLeft]; + [label1 setTextAlignment: NSTextAlignmentLeft]; + [label2 setTextAlignment: NSTextAlignmentLeft]; r1.origin.y = -1; // make it fit in landscape r2.origin.y = r1.origin.y + r1.size.height - 2; r3.size.height = r1.size.height + r2.size.height; @@ -112,15 +114,33 @@ [v addSubview:label1]; [v addSubview:label2]; + // Default opacity looks bad. + [v setBackgroundColor:[[v backgroundColor] colorWithAlphaComponent:1]]; + self.navigationItem.titleView = v; + + win.origin.x = 0; + win.origin.y = 0; + win.size.height = 44; // #### This cannot possibly be right. + UISearchBar *search = [[UISearchBar alloc] initWithFrame:win]; + search.delegate = self; + search.placeholder = @"Search..."; + self.tableView.tableHeaderView = search; + + // Dismiss the search field's keyboard as soon as we scroll. +# ifdef __IPHONE_7_0 + if ([self.tableView respondsToSelector:@selector(keyboardDismissMode)]) + [self.tableView setKeyboardDismissMode: + UIScrollViewKeyboardDismissModeOnDrag]; +# endif } -- (id)initWithNames:(NSArray *)names descriptions:(NSDictionary *)descs; +- (id)initWithNames:(NSArray *)_names descriptions:(NSDictionary *)_descs; { self = [self init]; if (! self) return 0; - [self reload:names descriptions:descs]; + [self reload:_names descriptions:_descs search:nil]; [self makeTitleBar]; return self; } @@ -131,6 +151,8 @@ int n = countof(list_by_letter); NSMutableArray *a = [NSMutableArray arrayWithCapacity: n]; for (int i = 0; i < n; i++) { + if ([list_by_letter[i] count] == 0) // Omit empty letter sections. + continue; char s[2]; s[0] = (i == 'Z'-'A'+1 ? '#' : i+'A'); s[1] = 0; @@ -141,11 +163,25 @@ } -- (void) reload:(NSArray *)names descriptions:(NSDictionary *)descs +/* Called when text is typed into the top search bar. + */ +- (void)searchBar:(UISearchBar *)bar textDidChange:(NSString *)txt { - if (descriptions) - [descriptions release]; - descriptions = [descs retain]; + [self reload:names descriptions:descriptions search:txt]; +} + + +- (void) reload:(NSArray *)_names descriptions:(NSDictionary *)_descs + search:search +{ + if (names != _names) { + if (names) [names release]; + names = [_names retain]; + } + if (_descs != descriptions) { + if (descriptions) [descriptions release]; + descriptions = [_descs retain]; + } int n = countof(list_by_letter); for (int i = 0; i < n; i++) { @@ -153,6 +189,25 @@ } for (NSString *name in names) { + + // If we're searching, omit any items that don't have a match in the + // title or description. + // + BOOL matchp = (!search || [search length] == 0); + if (! matchp) { + matchp = ([name rangeOfString:search + options:NSCaseInsensitiveSearch].location + != NSNotFound); + } + if (! matchp) { + NSString *desc = [descriptions objectForKey:name]; + matchp = ([desc rangeOfString:search + options:NSCaseInsensitiveSearch].location + != NSNotFound); + } + if (! matchp) + continue; + int index = ([name cStringUsingEncoding: NSASCIIStringEncoding])[0]; if (index >= 'a' && index <= 'z') index -= 'a'-'A'; @@ -215,25 +270,23 @@ - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)ip { - NSString *id = + NSString *title = [[letter_sections objectAtIndex: [ip indexAtPosition: 0]] objectAtIndex: [ip indexAtPosition: 1]]; - NSString *desc = [descriptions objectForKey:id]; + NSString *desc = [descriptions objectForKey:title]; - UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier: id]; - if (!cell) { + NSString *id = @"Cell"; + UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:id]; + if (!cell) cell = [[[UITableViewCell alloc] - initWithStyle: (desc - ? UITableViewCellStyleSubtitle - : UITableViewCellStyleDefault) + initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: id] autorelease]; - cell.textLabel.text = id; - cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; - if (desc) - cell.detailTextLabel.text = desc; - } + cell.textLabel.text = title; + cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; + cell.detailTextLabel.text = desc; + return cell; } @@ -247,6 +300,10 @@ SaverRunner *s = (SaverRunner *) [[UIApplication sharedApplication] delegate]; if (! s) return; + + // Dismiss the search field's keyboard before launching a saver. + [self.tableView.tableHeaderView resignFirstResponder]; + NSAssert ([s isKindOfClass:[SaverRunner class]], @"not a SaverRunner"); [s loadSaver: cell.textLabel.text]; } @@ -289,12 +346,6 @@ } -- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)o -{ - return YES; -} - - /* We need this to respond to "shake" gestures */ - (BOOL)canBecomeFirstResponder @@ -315,6 +366,8 @@ */ - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { + if (motion != UIEventSubtypeMotionShake) + return; NSMutableArray *a = [NSMutableArray arrayWithCapacity: 200]; for (NSArray *sec in letter_sections) for (NSString *s in sec)