-/* xscreensaver, Copyright (c) 2006 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2008 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
label);
}
+ // If either the min or max field contains a decimal point, then this
+ // option may have a floating point value; otherwise, it is constrained
+ // to be an integer.
+ //
+ NSCharacterSet *dot =
+ [NSCharacterSet characterSetWithCharactersInString:@"."];
+ BOOL float_p = ([low rangeOfCharacterFromSet:dot].location != NSNotFound ||
+ [high rangeOfCharacterFromSet:dot].location != NSNotFound);
+
if ([type isEqualToString:@"slider"]) {
NSRect rect;
rect.origin.x = rect.origin.y = 0;
rect.size.width = 150;
- rect.size.height = 20;
+ rect.size.height = 23; // apparent min height for slider with ticks...
NSSlider *slider;
if (cvt)
slider = [[InvertedSlider alloc] initWithFrame:rect];
[slider setMaxValue:[high doubleValue]];
[slider setMinValue:[low doubleValue]];
+ int range = [slider maxValue] - [slider minValue] + 1;
+ int range2 = range;
+ int max_ticks = 21;
+ while (range2 > max_ticks)
+ range2 /= 10;
+
+ // If we have elided ticks, leave it at the max number of ticks.
+ if (range != range2 && range2 < max_ticks)
+ range2 = max_ticks;
+
+ // If it's a float, always display the max number of ticks.
+ if (float_p && range2 < max_ticks)
+ range2 = max_ticks;
+
+ [slider setNumberOfTickMarks:range2];
+
+ [slider setAllowsTickMarkValuesOnly:
+ (range == range2 && // we are showing the actual number of ticks
+ !float_p)]; // and we want integer results
+
+ // #### Note: when the slider's range is large enough that we aren't
+ // showing all possible ticks, the slider's value is not constrained
+ // to be an integer, even though it should be...
+ // Maybe we need to use a value converter or something?
+
if (label) {
NSTextField *lab = make_label (label);
place_child (parent, lab, NO);
[step sizeToFit];
place_child (parent, step, YES);
rect = [step frame];
- rect.size.height = [txt frame].size.height;
rect.origin.x -= COLUMN_SPACING; // this one goes close
+ rect.origin.y += ([txt frame].size.height - rect.size.height) / 2;
[step setFrame:rect];
[step setMinValue:[low doubleValue]];
else
[step setIncrement:1.0];
+ NSNumberFormatter *fmt = [[[NSNumberFormatter alloc] init] autorelease];
+ [fmt setFormatterBehavior:NSNumberFormatterBehavior10_4];
+ [fmt setNumberStyle:NSNumberFormatterDecimalStyle];
+ [fmt setMinimum:[NSNumber numberWithDouble:[low doubleValue]]];
+ [fmt setMaximum:[NSNumber numberWithDouble:[high doubleValue]]];
+ [fmt setMinimumFractionDigits: (float_p ? 1 : 0)];
+ [fmt setMaximumFractionDigits: (float_p ? 2 : 0)];
+
+ [fmt setGeneratesDecimalNumbers:float_p];
+ [[txt cell] setFormatter:fmt];
+
+
bind_switch_to_preferences (prefs, step, arg, opts);
bind_switch_to_preferences (prefs, txt, arg, opts);
}
+static char *
+anchorize (const char *url)
+{
+ const char *wiki = "http://en.wikipedia.org/wiki/";
+ if (!strncmp (wiki, url, strlen(wiki))) {
+ char *anchor = (char *) malloc (strlen(url) * 3 + 10);
+ strcpy (anchor, "Wikipedia: \"");
+ const char *in = url + strlen(wiki);
+ char *out = anchor + strlen(anchor);
+ while (*in) {
+ if (*in == '_') {
+ *out++ = ' ';
+ } else if (*in == '#') {
+ *out++ = ':';
+ *out++ = ' ';
+ } else if (*in == '%') {
+ char hex[3];
+ hex[0] = in[1];
+ hex[1] = in[2];
+ hex[2] = 0;
+ int n = 0;
+ sscanf (hex, "%x", &n);
+ *out++ = (char) n;
+ in += 2;
+ } else {
+ *out++ = *in;
+ }
+ in++;
+ }
+ *out++ = '"';
+ *out = 0;
+ return anchor;
+
+ } else {
+ return strdup (url);
+ }
+}
+
+
/* Converts any http: URLs in the given text field to clickable links.
*/
static void
NSString *nsurl = [text substringWithRange:r2];
const char *url = [nsurl UTF8String];
- // Construct the RTF corresponding to <A HREF="url">url</A>
+ // If this is a Wikipedia URL, make the linked text be prettier.
+ //
+ char *anchor = anchorize(url);
+
+ // Construct the RTF corresponding to <A HREF="url">anchor</A>
//
const char *fmt = "{\\field{\\*\\fldinst{HYPERLINK \"%s\"}}%s}";
- char *rtf = malloc (strlen (fmt) + (strlen (url) * 2) + 10);
- sprintf (rtf, fmt, url, url);
+ char *rtf = malloc (strlen (fmt) + strlen(url) + strlen(anchor) + 10);
+ sprintf (rtf, fmt, url, anchor);
+ free (anchor);
NSData *rtfdata = [NSData dataWithBytesNoCopy:rtf length:strlen(rtf)];
// Insert the RTF into the NSText.
[nstext replaceCharactersInRange:r2 withRTF:rtfdata];
+
+ int L2 = [text length]; // might have changed
+ start.location -= (L - L2);
+ L = L2;
}
}
{
/*
Display Text:
- (x) Computer Name and Time
+ (x) Computer name and time
( ) Text [__________________________]
( ) Text file [_________________] [Choose]
( ) URL [__________________________]
[matrix setAllowsEmptySelection:NO];
NSArrayController *cnames = [[NSArrayController alloc] initWithContent:nil];
- [cnames addObject:@"Computer Name and Time"];
+ [cnames addObject:@"Computer name and time"];
[cnames addObject:@"Text"];
[cnames addObject:@"File"];
[cnames addObject:@"URL"];
NSView *parent, NSXMLNode *node)
{
/*
- [x] Grab Desktop Images
- [ ] Choose Random Image:
+ [x] Grab desktop images
+ [ ] Choose random image:
[__________________________] [Choose]
- <boolean id="grabDesktopImages" _label="Grab Desktop Images"
+ <boolean id="grabDesktopImages" _label="Grab desktop images"
arg-unset="-no-grab-desktop"/>
- <boolean id="chooseRandomImages" _label="Grab Desktop Images"
+ <boolean id="chooseRandomImages" _label="Grab desktop images"
arg-unset="-choose-random-images"/>
<file id="imageDirectory" _label="" arg-set="-image-directory %"/>
*/
[node2 setAttributesAsDictionary:
[NSDictionary dictionaryWithObjectsAndKeys:
@"grabDesktopImages", @"id",
- @"Grab Desktop Images", @"_label",
+ @"Grab desktop images", @"_label",
@"-no-grab-desktop", @"arg-unset",
nil]];
make_checkbox (prefs, opts, parent, node2);
[node2 setAttributesAsDictionary:
[NSDictionary dictionaryWithObjectsAndKeys:
@"chooseRandomImages", @"id",
- @"Choose Random Images", @"_label",
+ @"Choose random images", @"_label",
@"-choose-random-images", @"arg-set",
nil]];
make_checkbox (prefs, opts, parent, node2);
[node2 setAttributesAsDictionary:
[NSDictionary dictionaryWithObjectsAndKeys:
@"imageDirectory", @"id",
- @"Images Directory:", @"_label",
+ @"Images directory:", @"_label",
@"-image-directory %", @"arg",
nil]];
make_file_selector (prefs, opts, parent, node2, YES, NO);
[pbox setTitlePosition:NSNoTitle];
[pbox setBorderType:NSBezelBorder];
+ // Enforce a max height on the dialog, so that it's obvious to me
+ // (on a big screen) when the dialog will fall off the bottom of
+ // a small screen (e.g., 1024x768 laptop with a huge bottom dock).
{
NSRect f = [panel frame];
- int screen_height = 800 - 64;
+ int screen_height = (768 // shortest "modern" Mac display
+ - 22 // menu bar
+ - 56 // System Preferences toolbar
+ - 140 // default magnified bottom dock icon
+ );
if (f.size.height > screen_height) {
NSLog(@"%@ height was %.0f; clipping to %d",
[panel class], f.size.height, screen_height);