1// 2// ZoomPreferenceWindow.m 3// ZoomCocoa 4// 5// Created by Andrew Hunter on Sat Dec 20 2003. 6// Copyright (c) 2003 Andrew Hunter. All rights reserved. 7// 8 9// Modifications by Collin Pieper to add transparency support 10 11#import "ZoomPreferenceWindow.h" 12#import "ZoomStoryOrganiser.h" 13 14 15static NSToolbarItem* generalSettingsItem; 16static NSToolbarItem* gameSettingsItem; 17static NSToolbarItem* displaySettingsItem; 18static NSToolbarItem* fontSettingsItem; 19static NSToolbarItem* colourSettingsItem; 20static NSToolbarItem* typographicSettingsItem; 21 22static NSDictionary* itemDictionary = nil; 23 24@implementation ZoomPreferenceWindow 25 26+ (void) initialize { 27 // Create the toolbar items 28 generalSettingsItem = [[NSToolbarItem alloc] initWithItemIdentifier: @"generalSettings"]; 29 gameSettingsItem = [[NSToolbarItem alloc] initWithItemIdentifier: @"gameSettings"]; 30 displaySettingsItem = [[NSToolbarItem alloc] initWithItemIdentifier: @"displaySettings"]; 31 fontSettingsItem = [[NSToolbarItem alloc] initWithItemIdentifier: @"fontSettings"]; 32 colourSettingsItem = [[NSToolbarItem alloc] initWithItemIdentifier: @"colourSettings"]; 33 typographicSettingsItem = [[NSToolbarItem alloc] initWithItemIdentifier: @"typographicSettings"]; 34 35 // ... and the dictionary 36 itemDictionary = [[NSDictionary dictionaryWithObjectsAndKeys: 37 generalSettingsItem, @"generalSettings", 38 gameSettingsItem, @"gameSettings", 39 displaySettingsItem, @"displaySettings", 40 fontSettingsItem, @"fontSettings", 41 colourSettingsItem, @"colourSettings", 42 typographicSettingsItem, @"typographicSettings", 43 nil] retain]; 44 45 // Set up the items 46 [generalSettingsItem setLabel: @"General"]; 47 [generalSettingsItem setImage: [[[NSImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForImageResource: @"generalSettings"]] autorelease]]; 48 [gameSettingsItem setLabel: @"Game"]; 49 [gameSettingsItem setImage: [[[NSImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForImageResource: @"gameSettings"]] autorelease]]; 50 [displaySettingsItem setLabel: @"Display"]; 51 [displaySettingsItem setImage: [[[NSImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForImageResource: @"displaySettings"]] autorelease]]; 52 [fontSettingsItem setLabel: @"Fonts"]; 53 [fontSettingsItem setImage: [[[NSImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForImageResource: @"fontSettings"]] autorelease]]; 54 [colourSettingsItem setLabel: @"Colour"]; 55 [colourSettingsItem setImage: [[[NSImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForImageResource: @"colourSettings"]] autorelease]]; 56 [typographicSettingsItem setLabel: @"Typography"]; 57 [typographicSettingsItem setImage: [[[NSImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForImageResource: @"typographicSettings"]] autorelease]]; 58 59 // And the actions 60 [generalSettingsItem setAction: @selector(generalSettings:)]; 61 [gameSettingsItem setAction: @selector(gameSettings:)]; 62 [displaySettingsItem setAction: @selector(displaySettings:)]; 63 [fontSettingsItem setAction: @selector(fontSettings:)]; 64 [colourSettingsItem setAction: @selector(colourSettings:)]; 65 [typographicSettingsItem setAction: @selector(typographicSettings:)]; 66} 67 68- (id) init { 69 return [self initWithWindowNibName: @"Preferences"]; 70} 71 72- (void) dealloc { 73 if (toolbar) [toolbar release]; 74 if (prefs) [prefs release]; 75 76 [[NSNotificationCenter defaultCenter] removeObserver: self]; 77 78 [super dealloc]; 79} 80 81static int familyComparer(id a, id b, void* context) { 82 NSString* family1 = a; 83 NSString* family2 = b; 84 85 return [family1 caseInsensitiveCompare: family2]; 86} 87 88- (NSMenu*) fontMenu: (BOOL) fixed { 89 // Constructs a menu of fonts 90 // (Apple want us to use the font selection panel, but it feels clunky for the 'simple' view: there's no good way to associate 91 // it with the style we're selecting. Plus we want to select families, not individual fonts) 92 NSFontManager* mgr = [NSFontManager sharedFontManager]; 93 94 NSMenu* result = [[NSMenu alloc] init]; 95 96 // Iterate through the available font families and create menu items 97 NSEnumerator* familyEnum = [[[mgr availableFontFamilies] sortedArrayUsingFunction: familyComparer 98 context: nil] objectEnumerator]; 99 NSString* family; 100 101 while (family = [familyEnum nextObject]) { 102 // Get the font 103 NSFont* sampleFont = [mgr fontWithFamily: family 104 traits: 0 105 weight: 5 106 size: 13.0]; 107 108 if (!sampleFont) continue; 109 if (fixed && ![sampleFont isFixedPitch]) { 110 // Skip this font 111 continue; 112 } 113 114 // Construct the item 115 NSMenuItem* fontItem = [[NSMenuItem alloc] init]; 116 [fontItem setAttributedTitle: 117 [[[NSAttributedString alloc] initWithString: family 118 attributes: [NSDictionary dictionaryWithObject: sampleFont 119 forKey: NSFontAttributeName]] autorelease]]; 120 121 // Add to the menu 122 [result addItem: [fontItem autorelease]]; 123 } 124 125 // Return the result 126 return [result autorelease]; 127} 128 129- (void) windowDidLoad { 130 // Set the toolbar 131 toolbar = [[NSToolbar allocWithZone: [self zone]] initWithIdentifier: @"preferencesToolbar2"]; 132 133 [toolbar setDelegate: self]; 134 [toolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel]; 135 [toolbar setAllowsUserCustomization: NO]; 136 137 [[self window] setToolbar: toolbar]; 138 139 [[self window] setContentSize: [generalSettingsView frame].size]; 140 [[self window] setContentView: generalSettingsView]; 141 142 if ([toolbar respondsToSelector: @selector(setSelectedItemIdentifier:)]) { 143 [toolbar setSelectedItemIdentifier: @"generalSettings"]; 144 } 145 146 147 [fonts setDataSource: self]; 148 [fonts setDelegate: self]; 149 [colours setDataSource: self]; 150 [colours setDelegate: self]; 151 152 // Set up the various font menus 153 NSMenu* proportionalMenu = [self fontMenu: NO]; 154 NSMenu* fixedMenu = [self fontMenu: YES]; 155 NSMenu* symbolMenu = [[proportionalMenu copy] autorelease]; 156 157 [proportionalFont setMenu: proportionalMenu]; 158 [fixedFont setMenu: fixedMenu]; 159 [symbolicFont setMenu: symbolMenu]; 160 161 [[NSNotificationCenter defaultCenter] addObserver: self 162 selector: @selector(storyProgressChanged:) 163 name: ZoomStoryOrganiserProgressNotification 164 object: [ZoomStoryOrganiser sharedStoryOrganiser]]; 165} 166 167// == Setting the pane that's being displayed == 168 169- (void) switchToPane: (NSView*) preferencePane { 170 if ([[self window] contentView] == preferencePane) return; 171 172 // Select the appropriate item in the toolbar 173 if ([toolbar respondsToSelector: @selector(setSelectedItemIdentifier:)]) { 174 NSString* selected = nil; 175 176 if (preferencePane == generalSettingsView) { 177 selected = @"generalSettings"; 178 } else if (preferencePane == gameSettingsView) { 179 selected = @"gameSettings"; 180 } else if (preferencePane == displaySettingsView) { 181 selected = @"displaySettings"; 182 } else if (preferencePane == fontSettingsView) { 183 selected = @"fontSettings"; 184 } else if (preferencePane == colourSettingsView) { 185 selected = @"colourSettings"; 186 } else if (preferencePane == typographicalSettingsView) { 187 selected = @"typographicSettings"; 188 } 189 190 if (selected != nil) { 191 [toolbar setSelectedItemIdentifier: selected]; 192 } 193 } 194 195 // Work out the various frame sizes 196 NSRect currentFrame = [[[self window] contentView] frame]; 197 NSRect oldFrame = currentFrame; 198 NSRect windowFrame = [[self window] frame]; 199 200 currentFrame.origin.y -= [preferencePane frame].size.height - currentFrame.size.height; 201 currentFrame.size.height = [preferencePane frame].size.height; 202 203 // Grr, complicated, as OS X provides no way to work out toolbar proportions except in 10.3 204 windowFrame.origin.x += (currentFrame.origin.x - oldFrame.origin.x); 205 windowFrame.origin.y += (currentFrame.origin.y - oldFrame.origin.y); 206 windowFrame.size.width += (currentFrame.size.width - oldFrame.size.width); 207 windowFrame.size.height += (currentFrame.size.height - oldFrame.size.height); 208 209 [[self window] setContentView: [[[NSView alloc] init] autorelease]]; 210 [[self window] setFrame: windowFrame 211 display: YES 212 animate: YES]; 213 [[self window] setContentView: preferencePane]; 214 [[self window] setInitialFirstResponder: preferencePane]; 215} 216 217// == Toolbar delegate functions == 218 219- (NSToolbarItem *)toolbar: (NSToolbar *) toolbar 220 itemForItemIdentifier: (NSString *) itemIdentifier 221 willBeInsertedIntoToolbar: (BOOL) flag { 222 return [itemDictionary objectForKey: itemIdentifier]; 223} 224 225- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar { 226 return [NSArray arrayWithObjects: 227 @"generalSettings", @"gameSettings", @"displaySettings", @"fontSettings", @"typographicSettings", @"colourSettings", NSToolbarFlexibleSpaceItemIdentifier, 228 nil]; 229} 230 231- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar { 232 return [NSArray arrayWithObjects: 233 NSToolbarFlexibleSpaceItemIdentifier, @"generalSettings", @"gameSettings", @"displaySettings", @"fontSettings", @"typographicSettings", @"colourSettings", NSToolbarFlexibleSpaceItemIdentifier, 234 nil]; 235} 236 237- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar { 238 return [NSArray arrayWithObjects: 239 @"generalSettings", @"gameSettings", @"displaySettings", @"fontSettings", @"colourSettings", @"typographicSettings", 240 nil]; 241} 242 243// == Toolbar actions == 244 245- (void) generalSettings: (id) sender { 246 [self switchToPane: generalSettingsView]; 247} 248 249- (void) gameSettings: (id) sender { 250 [self switchToPane: gameSettingsView]; 251} 252 253- (void) displaySettings: (id) sender { 254 [self switchToPane: displaySettingsView]; 255} 256 257- (void) fontSettings: (id) sender { 258 [self switchToPane: fontSettingsView]; 259} 260 261- (void) colourSettings: (id) sender { 262 [self switchToPane: colourSettingsView]; 263} 264 265- (void) typographicSettings: (id) sender { 266 [self switchToPane: typographicalSettingsView]; 267} 268 269// == Setting the preferences that we're editing == 270 271- (void) setButton: (NSPopUpButton*) button 272 toFontFamily: (NSString*) family { 273 NSMenuItem* familyItem = nil; 274 NSEnumerator* itemEnum = [[[button menu] itemArray] objectEnumerator]; 275 NSMenuItem* curItem; 276 277 while (curItem = [itemEnum nextObject]) { 278 if ([[curItem title] caseInsensitiveCompare: family] == NSEqualToComparison) { 279 familyItem = curItem; 280 break; 281 } 282 } 283 284 if (familyItem) { 285 [button selectItem: familyItem]; 286 } 287} 288 289- (void) setSimpleFonts { 290 // Sets our display from the 'simple' fonts the user has selected 291 292 // Select the fonts 293 [self setButton: proportionalFont 294 toFontFamily: [prefs proportionalFontFamily]]; 295 [self setButton: fixedFont 296 toFontFamily: [prefs fixedFontFamily]]; 297 [self setButton: symbolicFont 298 toFontFamily: [prefs symbolicFontFamily]]; 299 300 // Set the size display 301 float fontSize = [prefs fontSize]; 302 [fontSizeSlider setFloatValue: fontSize]; 303 [fontSizeDisplay setStringValue: [NSString stringWithFormat: @"%.1fpt", fontSize]]; 304 305 // Set the font preview 306 [fontPreview setFont: [[prefs fonts] objectAtIndex: 0]]; 307} 308 309- (NSString*) colourNameAtIndex: (int) index { 310 switch (index) { 311 case 0: return @"Black"; 312 case 1: return @"Red"; 313 case 2: return @"Green"; 314 case 3: return @"Yellow"; 315 case 4: return @"Blue"; 316 case 5: return @"Magenta"; 317 case 6: return @"Cyan"; 318 case 7: return @"White"; 319 case 8: return @"Light grey"; 320 case 9: return @"Medium grey"; 321 case 10: return @"Dark grey"; 322 default: return @"Unused colour"; 323 } 324} 325 326- (void) selectItemWithTag: (int) tag 327 inPopup: (NSPopUpButton*) button { 328 int index; 329 330 for (index=0; index < [[button itemArray] count]; index++) { 331 if ([[button itemAtIndex: index] tag] == tag) { 332 [button selectItemAtIndex: index]; 333 return; 334 } 335 } 336} 337 338- (void) updateColourMenus { 339 NSMenu* newColourMenu = [[[NSMenu alloc] init] autorelease]; 340 341 int col; 342 for (col=0; col<10; col++) { 343 // Build the image showing a preview of this colour 344 NSImage* sampleImage = [[NSImage alloc] initWithSize: NSMakeSize(16, 12)]; 345 346 [sampleImage lockFocus]; 347 [[[prefs colours] objectAtIndex: col] set]; 348 NSRectFill(NSMakeRect(0,0,16,12)); 349 [sampleImage unlockFocus]; 350 351 // Build the actual menu item 352 NSMenuItem* colourItem = [[NSMenuItem alloc] initWithTitle: [self colourNameAtIndex: col] 353 action: nil 354 keyEquivalent: @""]; 355 [colourItem setTag: col]; 356 [colourItem setImage: sampleImage]; 357 358 // Add it to the menu 359 [newColourMenu addItem: colourItem]; 360 361 // Release our resources 362 [colourItem autorelease]; 363 [sampleImage autorelease]; 364 } 365 366 // Set the menu as the menu for both the popup buttons 367 [foregroundColour setMenu: newColourMenu]; 368 [backgroundColour setMenu: [[newColourMenu copy] autorelease]]; 369 370 [self selectItemWithTag: [prefs foregroundColour] 371 inPopup: foregroundColour]; 372 [self selectItemWithTag: [prefs backgroundColour] 373 inPopup: backgroundColour]; 374} 375 376- (void) setPreferences: (ZoomPreferences*) preferences { 377 if (prefs) [prefs release]; 378 prefs = [preferences retain]; 379 380 [displayWarnings setState: [prefs displayWarnings]?NSOnState:NSOffState]; 381 [fatalWarnings setState: [prefs fatalWarnings]?NSOnState:NSOffState]; 382 [speakGameText setState: [prefs speakGameText]?NSOnState:NSOffState]; 383 [scrollbackLength setFloatValue: [prefs scrollbackLength]]; 384 [keepGamesOrganised setState: [prefs keepGamesOrganised]?NSOnState:NSOffState]; 385 [autosaveGames setState: [prefs autosaveGames]?NSOnState:NSOffState]; 386 [reorganiseGames setEnabled: [prefs keepGamesOrganised]]; 387 [confirmGameClose setState: [prefs confirmGameClose]?NSOnState:NSOffState]; 388 [glulxInterpreter selectItemAtIndex: [glulxInterpreter indexOfItemWithTag: [prefs glulxInterpreter]]]; 389 390 // a kind of chessy way to get the current alpha setting 391 float red, green, blue, alpha; 392 NSColor * color = [[prefs colours] objectAtIndex:0]; 393 [color getRed:&red green:&green blue:&blue alpha:&alpha]; 394 [transparencySlider setFloatValue:(alpha * 100.0)]; 395 396 [interpreter selectItemAtIndex: [prefs interpreter]-1]; 397 [revision setStringValue: [NSString stringWithFormat: @"%c", [prefs revision]]]; 398 399 [self setSimpleFonts]; 400 401 [organiseDir setString: [prefs organiserDirectory]]; 402 403 [showMargins setState: [prefs textMargin] > 0?NSOnState:NSOffState]; 404 [useScreenFonts setState: [prefs useScreenFonts]?NSOnState:NSOffState]; 405 [useHyphenation setState: [prefs useHyphenation]?NSOnState:NSOffState]; 406 [kerning setState: [prefs useKerning]?NSOnState:NSOffState]; 407 [ligatures setState: [prefs useLigatures]?NSOnState:NSOffState]; 408 409 [marginWidth setEnabled: [prefs textMargin] > 0]; 410 if ([prefs textMargin] > 0) { 411 [marginWidth setFloatValue: [prefs textMargin]]; 412 } 413 414 [zoomBorders setState: [prefs showBorders]?NSOnState:NSOffState]; 415 [showCoverPicture setState: [prefs showCoverPicture]?NSOnState:NSOffState]; 416 [self updateColourMenus]; 417} 418 419// == Table data source == 420 421- (int)numberOfRowsInTableView: (NSTableView *)aTableView { 422 if (aTableView == fonts) return [[prefs fonts] count]; 423 if (aTableView == colours) return [[prefs colours] count]; 424 425 return 0; 426} 427 428static void appendStyle(NSMutableString* styleName, 429 NSString* newStyle) { 430 if ([styleName length] == 0) { 431 [styleName appendString: newStyle]; 432 } else { 433 [styleName appendString: @"-"]; 434 [styleName appendString: newStyle]; 435 } 436} 437 438- (id) tableView:(NSTableView *)aTableView 439 objectValueForTableColumn:(NSTableColumn *)aTableColumn 440 row:(int)rowIndex { 441 if (aTableView == fonts) { 442 // Fonts table 443 NSArray* fontArray = [prefs fonts]; 444 445 if ([[aTableColumn identifier] isEqualToString: @"Style"]) { 446 NSMutableString* name = [[@"" mutableCopy] autorelease]; 447 448 if (rowIndex&1) appendStyle(name, @"bold"); 449 if (rowIndex&2) appendStyle(name, @"italic"); 450 if (rowIndex&4) appendStyle(name, @"fixed"); 451 if (rowIndex&8) appendStyle(name, @"symbolic"); 452 453 if ([name isEqualToString: @""]) name = [[@"roman" mutableCopy] autorelease]; 454 455 return name; 456 } else if ([[aTableColumn identifier] isEqualToString: @"Font"]) { 457 NSString* fontName; 458 NSFont* font = [fontArray objectAtIndex: rowIndex]; 459 460 fontName = [NSString stringWithFormat: @"%@ (%.2gpt)", 461 [font fontName], 462 [font pointSize]]; 463 464 NSAttributedString* res; 465 466 res = [[[NSAttributedString alloc] initWithString: fontName 467 attributes: [NSDictionary dictionaryWithObject: font 468 forKey: NSFontAttributeName]] 469 autorelease]; 470 471 return res; 472 } 473 474 return @" -- "; 475 } 476 477 if (aTableView == colours) { 478 if ([[aTableColumn identifier] isEqualToString: @"Colour name"]) { 479 return [self colourNameAtIndex: rowIndex]; 480 } else if ([[aTableColumn identifier] isEqualToString: @"Colour"]) { 481 NSColor* theColour = [[prefs colours] objectAtIndex: rowIndex]; 482 NSAttributedString* res; 483 484 res = [[NSAttributedString alloc] initWithString: @"Sample" 485 attributes: [NSDictionary dictionaryWithObjectsAndKeys: 486 theColour, NSForegroundColorAttributeName, 487 theColour, NSBackgroundColorAttributeName, 488 nil]]; 489 490 return [res autorelease]; 491 } 492 493 return @" -- "; 494 } 495 496 return @" -- "; 497} 498 499// == Table delegate == 500 501- (void)tableViewSelectionDidChange:(NSNotification *)aNotification { 502 if ([aNotification object] == fonts) { 503 int selFont = [fonts selectedRow]; 504 505 if (selFont < 0) { 506 return; 507 } 508 509 NSFont* font = [[prefs fonts] objectAtIndex: selFont]; 510 511 // Display font panel 512 [[NSFontPanel sharedFontPanel] setPanelFont: font 513 isMultiple: NO]; 514 [[NSFontPanel sharedFontPanel] setEnabled: YES]; 515 [[NSFontPanel sharedFontPanel] setAccessoryView: nil]; 516 [[NSFontPanel sharedFontPanel] orderFront: self]; 517 [[NSFontPanel sharedFontPanel] reloadDefaultFontFamilies]; 518 } else if ([aNotification object] == colours) { 519 int selColour = [colours selectedRow]; 520 521 if (selColour < 0) { 522 return; 523 } 524 525 NSColor* colour = [[prefs colours] objectAtIndex: selColour]; 526 527 // Display colours 528 [[NSColorPanel sharedColorPanel] setColor: colour]; 529 [[NSColorPanel sharedColorPanel] setAccessoryView: nil]; 530 [[NSColorPanel sharedColorPanel] orderFront: self]; 531 } 532} 533 534// == Font panel delegate == 535 536- (void) changeFont:(id) sender { 537 // Change the selected font in the font table 538 int selFont = [fonts selectedRow]; 539 540 if (selFont < 0) return; 541 542 NSMutableArray* prefFonts = [[prefs fonts] mutableCopy]; 543 NSFont* newFont; 544 545 newFont = [sender convertFont: [prefFonts objectAtIndex: selFont]]; 546 547 if (newFont) { 548 [prefFonts replaceObjectAtIndex: selFont 549 withObject: newFont]; 550 [prefs setFonts: prefFonts]; 551 552 [fonts reloadData]; 553 } 554 555 [prefFonts release]; 556 557 [self setSimpleFonts]; 558} 559 560- (void)changeColor:(id)sender { 561 int selColour = [colours selectedRow]; 562 563 if (selColour < 0) { 564 return; 565 } 566 567 NSColor* selected_colour = [[NSColorPanel sharedColorPanel] color]; 568 NSColor* colour = [[selected_colour colorUsingColorSpaceName: NSCalibratedRGBColorSpace] colorWithAlphaComponent:(([transparencySlider floatValue] / 100.0))]; 569 570 NSMutableArray* cols = [[prefs colours] mutableCopy]; 571 572 if (colour) { 573 [cols replaceObjectAtIndex: selColour 574 withObject: colour]; 575 [prefs setColours: cols]; 576 577 [colours reloadData]; 578 [self updateColourMenus]; 579 } 580 581 [cols release]; 582} 583 584- (void)changeTransparency:(id)sender { 585 NSMutableArray* cols = [[prefs colours] mutableCopy]; 586 587 int i; 588 for( i = 0; i < [cols count]; i++ ) 589 { 590 NSColor * color = [cols objectAtIndex: i]; 591 592 NSColor* transparent_color = [[color colorUsingColorSpaceName: NSCalibratedRGBColorSpace] colorWithAlphaComponent:([transparencySlider floatValue] / 100.0)]; 593 594 [cols replaceObjectAtIndex: i 595 withObject: transparent_color]; 596 } 597 598 [prefs setColours: cols]; 599 600 [colours reloadData]; 601 602 [cols release]; 603} 604 605// == Various actions == 606 607- (IBAction) interpreterChanged: (id) sender { 608 [prefs setInterpreter: [interpreter indexOfSelectedItem]+1]; 609} 610 611- (IBAction) glulxInterpreterChanged: (id) sender { 612 [prefs setGlulxInterpreter: [[glulxInterpreter selectedItem] tag]]; 613} 614 615- (IBAction) revisionChanged: (id) sender { 616 [prefs setRevision: [[revision stringValue] characterAtIndex: 0]]; 617} 618 619- (IBAction) displayWarningsChanged: (id) sender { 620 [prefs setDisplayWarnings: [sender state]==NSOnState]; 621} 622 623- (IBAction) fatalWarningsChanged: (id) sender { 624 [prefs setFatalWarnings: [sender state]==NSOnState]; 625} 626 627- (IBAction) speakGameTextChanged: (id) sender { 628 [prefs setSpeakGameText: [sender state]==NSOnState]; 629} 630 631- (IBAction) scrollbackChanged: (id) sender { 632 [prefs setScrollbackLength: [sender floatValue]]; 633} 634 635- (IBAction) autosaveChanged: (id) sender { 636 [prefs setAutosaveGames: [sender state]==NSOnState]; 637} 638 639- (IBAction) confirmGameCloseChanged: (id) sender { 640 [prefs setConfirmGameClose: [sender state]==NSOnState]; 641} 642 643- (IBAction) keepOrganisedChanged: (id) sender { 644 [prefs setKeepGamesOrganised: [sender state]==NSOnState]; 645 [reorganiseGames setEnabled: [sender state]==NSOnState]; 646 if ([sender state]==NSOffState) { 647 [autosaveGames setState: NSOffState]; 648 [prefs setAutosaveGames: NO]; 649 } 650} 651 652- (void) changeOrganiserDirTo: (NSOpenPanel *)sheet 653 returnCode: (int)returnCode 654 contextInfo: (void *)contextInfo { 655 if (returnCode != NSOKButton) return; 656 657 [[ZoomStoryOrganiser sharedStoryOrganiser] reorganiseStoriesTo: [sheet directory]]; 658 [prefs setOrganiserDirectory: [sheet directory]]; 659 [organiseDir setString: [prefs organiserDirectory]]; 660} 661 662- (IBAction) changeOrganiseDir: (id) sender { 663 NSOpenPanel* dirChooser = [NSOpenPanel openPanel]; 664 665 [dirChooser setAllowsMultipleSelection: NO]; 666 [dirChooser setCanChooseDirectories: YES]; 667 [dirChooser setCanChooseFiles: NO]; 668 [dirChooser setCanCreateDirectories: YES]; 669 670 NSString* path = [prefs organiserDirectory]; 671 672 [dirChooser beginSheetForDirectory: path 673 file: nil 674 types: nil 675 modalForWindow: [self window] 676 modalDelegate: self 677 didEndSelector: @selector(changeOrganiserDirTo:returnCode:contextInfo:) 678 contextInfo: nil]; 679} 680 681- (IBAction) resetOrganiseDir: (id) sender { 682 if ([prefs keepGamesOrganised]) { 683 [[ZoomStoryOrganiser sharedStoryOrganiser] reorganiseStoriesTo: [ZoomPreferences defaultOrganiserDirectory]]; 684 } 685 [prefs setOrganiserDirectory: nil]; 686 [organiseDir setString: [prefs organiserDirectory]]; 687} 688 689 690- (IBAction) simpleFontsChanged: (id) sender { 691 // This action applies to all the font controls 692 693 // Set the size, if it has changed 694 float newSize = floorf([fontSizeSlider floatValue]); 695 if (newSize != [prefs fontSize]) [prefs setFontSize: newSize]; 696 697 // Set the families, if they've changed 698 NSString* propFamily = [[proportionalFont selectedItem] title]; 699 NSString* fixedFamily = [[fixedFont selectedItem] title]; 700 NSString* symbolicFamily = [[symbolicFont selectedItem] title]; 701 702 if (![propFamily isEqualToString: [prefs proportionalFontFamily]]) [prefs setProportionalFontFamily: propFamily]; 703 if (![fixedFamily isEqualToString: [prefs fixedFontFamily]]) [prefs setFixedFontFamily: fixedFamily]; 704 if (![symbolicFamily isEqualToString: [prefs symbolicFontFamily]]) [prefs setSymbolicFontFamily: symbolicFamily]; 705 706 // Update the display 707 [self setSimpleFonts]; 708} 709 710// = Typographical changes = 711 712- (IBAction) marginsChanged: (id) sender { 713 // Work out the new margin size 714 float oldSize = [prefs textMargin]; 715 float newSize; 716 717 if ([showMargins state] == NSOffState) { 718 newSize = 0; 719 [marginWidth setEnabled: NO]; 720 } else if ([showMargins state] == NSOnState && oldSize <= 0) { 721 newSize = 10.0; 722 [marginWidth setEnabled: YES]; 723 } else { 724 newSize = floorf([marginWidth floatValue]); 725 [marginWidth setEnabled: YES]; 726 } 727 728 if (newSize != oldSize) { 729 [prefs setTextMargin: newSize]; 730 } 731} 732 733- (IBAction) screenFontsChanged: (id) sender { 734 BOOL newState = [useScreenFonts state]==NSOnState; 735 736 if (newState != [prefs useScreenFonts]) { 737 [prefs setUseScreenFonts: newState]; 738 } 739} 740 741- (IBAction) hyphenationChanged: (id) sender { 742 BOOL newState = [useHyphenation state]==NSOnState; 743 744 if (newState != [prefs useHyphenation]) { 745 [prefs setUseHyphenation: newState]; 746 } 747} 748 749- (IBAction) ligaturesChanged: (id) sender { 750 BOOL newState = [ligatures state]==NSOnState; 751 752 if (newState != [prefs useLigatures]) { 753 [prefs setUseLigatures: newState]; 754 } 755} 756 757- (IBAction) kerningChanged: (id) sender { 758 BOOL newState = [kerning state]==NSOnState; 759 760 if (newState != [prefs useKerning]) { 761 [prefs setUseKerning: newState]; 762 } 763} 764 765// = Story progress meter = 766 767- (void) storyProgressChanged: (NSNotification*) not { 768 NSDictionary* userInfo = [not userInfo]; 769 BOOL activated = [[userInfo objectForKey: @"ActionStarting"] boolValue]; 770 771 if (activated) { 772 indicatorCount++; 773 } else { 774 indicatorCount--; 775 } 776 777 if (indicatorCount <= 0) { 778 indicatorCount = 0; 779 [organiserIndicator stopAnimation: self]; 780 } else { 781 [organiserIndicator startAnimation: self]; 782 } 783} 784 785- (IBAction) reorganiseGames: (id) sender { 786 // Can't use this if keepGamesOrganised is off 787 if (![prefs keepGamesOrganised]) return; 788 789 // Reorganise all the stories 790 [[ZoomStoryOrganiser sharedStoryOrganiser] organiseAllStories]; 791} 792 793// = Display pane = 794 795- (IBAction) bordersChanged: (id) sender { 796 BOOL newState = [sender state] == NSOnState; 797 BOOL oldState = [prefs showBorders]; 798 799 if (newState != oldState) { 800 [prefs setShowBorders: newState]; 801 [prefs setShowGlkBorders: newState]; 802 } 803} 804 805- (IBAction) showCoverPictureChanged: (id) sender { 806 BOOL newState = [sender state] == NSOnState; 807 BOOL oldState = [prefs showCoverPicture]; 808 809 if (newState != oldState) { 810 [prefs setShowCoverPicture: newState]; 811 } 812} 813 814- (IBAction) colourChanged: (id) sender { 815 int newValue = [sender selectedTag]; 816 int oldValue = (sender==foregroundColour)?[prefs foregroundColour]:[prefs backgroundColour]; 817 818 if (newValue != oldValue) { 819 if (sender == foregroundColour) { 820 [prefs setForegroundColour: newValue]; 821 } else { 822 [prefs setBackgroundColour: newValue]; 823 } 824 } 825} 826 827@end 828